À rendre (livrables)
2021-12-09: un fichier nom1_nom2.Rmd qui peut être tricoté (knitted) sous rstudio.
Votre fichier doit être tricoté sans erreurs et le résultat doit être un document html qui peut être visualisé dans un navigateur moderne.
Le fichier doit contenir le code utilisé pour construire les graphiques et les résumés numériques.
Le fichier doit contenir le texte de vos commentaires (en anglais ou en français).
Les commentaires doivent être rédigés avec soin et précision et doivent être concis.
Le fichier nom1_nom2.Rmd sera téléchargé sur Moodle.
2021-12-14: une présentation orale de 20 minutes sur des éléments extraits de votre premier livrable nom1_nom2.Rmd.
La présentation consiste en un exposé de 12 minutes et 8 minutes de questions et réponses.
La présentation est soutenue par des diapositives
Les diapositives générées à partir de Rmarkdown doivent être privilégiées. Vous pouvez choisir le format que vous préférez (binb, xaringan, slidy, ioslides, …)
Objectifs
Ce carnet de notes a pour but de
travailler avec des tables (data.frames, tibbles, data.tables, …) en utilisant dplyr ou tout autre langage d’interrogation (tel que fourni par exemple par data.table)
visualiser des données démographiques comme celles fournies par [Human Mortality Database organization] (https://www.mortality.org ).
l’utilisation de l’ACP et d’autres méthodes matricielles pour explorer des ensembles de données multivariées (les tables de mortalité peuvent être considérées comme des ensembles de données multivariées).
Données des tables de mortalité
Les tables de données de vie ont été téléchargées à partir de https://www.mortality.org . Elles ont été élaborées pour vous et peuvent être téléchargées à partir de l’URL ‘https://www.dropbox.com/s/tnci38tqchxwic6/full_life_table.Rds?dl=0 ’, enregistrées dans votre répertoire de travail.
Si vous installez et chargez le paquet https://cran.r-project.org/web/packages/demography/index.html , vous trouverez également des tables de mortalité.
Nous étudions des tables de mortalité décrivant des pays d’Europe occidentale (France, Grande-Bretagne -en fait Angleterre et Pays de Galles-, Italie, Pays-Bas, Espagne et Suède) et les États-Unis.
Nous chargeons les tables de mortalité annuelles pour les femmes, les hommes et la population totale (both) des différents pays.
Téléchargez les données depuis https://www.dropbox.com/s/tnci38tqchxwic6/full_life_table.Rds?dl=0 dans votre répertoire de travail (working directory). Enregistrez-les sous le nom de full_life_table.Rds. Chargez-le en mémoire en utilisant readr::read_rds().
fpath <- 'full_life_table.Rds' # once you have downloaded the file
if (! file.exists(fpath)){
cat(glue('{fpath} should be in working directory!'))
} else {
life_table <- readr::read_rds(fpath)
glimpse(life_table)
}
Rows: 379,170 Columns: 12 $ Year 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816, 1816,~ $ Age 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 2~ $ mx 0.20534, 0.04669, 0.03412, 0.02304, 0.01604, 0.01373, 0.01186, 0.01016,~ $ qx 0.17972, 0.04562, 0.03355, 0.02277, 0.01591, 0.01364, 0.01179, 0.01011,~ $ ax 0.31, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50, 0.50,~ $ lx 100000, 82028, 78285, 75659, 73936, 72760, 71768, 70921, 70204, 69601, ~ $ dx 17972, 3742, 2626, 1723, 1176, 992, 846, 717, 604, 509, 423, 362, 325, ~ $ Lx 87524, 80156, 76972, 74798, 73348, 72264, 71344, 70563, 69902, 69346, 6~ $ Tx 4009912, 3922388, 3842232, 3765260, 3690462, 3617114, 3544850, 3473506,~ $ ex 40.10, 47.82, 49.08, 49.77, 49.91, 49.71, 49.39, 48.98, 48.47, 47.89, 4~ $ Country “France”, “France”, “France”, “France”, “France”, “France”, “France”, “~ $ Gender ”Both“,”Both“,”Both“,”Both“,”Both“,”Both“,”Both“,”Both“,”Both",~
Vérifiez sur http://www.mortality.org la signification des différentes colonnes:
Le document Tables de mortalité françaises pour les XIXe et XXe siècles et projections pour le XXIe siècle contient des informations détaillées sur la construction des Tables de mortalité pour la France. On peut en général distinguer deux types de Tables de mortalité : les Tables du moment qui contiennent pour chaque année civile, les risques de mortalité à différents âges pour cette même année ; et les Tables de génération qui contiennent pour une année de naissance donnée, les risques de mortalité auxquels un individu né au cours de cette année a été exposé.
Les tables de mortalité étudiées dans ce travail sont les Tables du moment . D’après le document de Vallin et Meslé, l’élaboration des tables de mortalité a nécessité des choix et un travail substantiel d’édition.
Voir (entre autres)
p. 19 Les variations brutales des quotients de mortalité à certains âges pour une année civile donnée
L’estimation des quotients de mortalité au grand âge.
Voir aussi les [schémas de Lexis] (https://en.wikipedia.org/wiki/Lexis_diagram ).
À partir de maintenant, la table universelle est nommée life_table.
Les tables de mortalité sur lesquelles vous allez travailler sont appelées tableaux de mortalité de l’année .
Année
nombre entier
Age
entier
Âge \(x\)
mx
double
Taux de mortalité central à l’âge \(x\) : \(m_x\)
qx
double
Probabilité de mourir entre l’âge de \(x\) et l’âge de \(x+1\) \(q_x = \frac{m_x}{1+ m_x/2}\)
lx
entier
Nombre de personnes encore en vie à l’âge de \(x\) dans une cohorte fictive de \(100000\)
dx
integer
Nombre de personnes décédées entre l’âge \(x\) et \(x+1\) durant l’année dans la cohorte fictive
Lx
entier
Nombre d’années-personnes vécues entre l’âge de \(x\) et \(x+1\) , \(L_x = \ell_x - d_x\times a_x\) dans la cohorte fictive
Tx
entier
ex
double
Espérance de vie résiduelle à l’âge \(x\)
Pays
facteur
Pays-Bas/…
Sexe
facteur
Féminin / Masculin
Voir Preston et al. pour les détails et les explications.
L’Ouest (de l’Europe) en 1948
On observe, pour l’année 1948, que le quotient de mortalité commence à un niveau élevé puis diminue jusqu’à l’âge de l’adolescence avant d’entreprendre une croissance monotone. Le graphe suit la même tendance quel que soit le pays. Cependant, il diffère selon le sexe. On peut observer un quotient de mortalité légèrement plus élevé chez les hommes.
Sur ce plotly on peut constater que durant l’année 1948, l’Espagne et l’Italie possédaient un taux de mortalité bien supérieur à celui des États-Unis et du reste de l’Europe. Ce rapport s’équilibre à l’âge de 40. On voit également que la courbe des femmes est supérieure à celle des hommes. Les autres pays quant à eux sont comparables au taux des USA.
Evolution des taux de mortalité depuis la seconde guerre mondiale
Warning: Transformation introduced infinite values in continuous y-axis
et qui renvoie un tableau de données avec le schéma :
Année
entier
Age
entier
qx
double
qx.ref_year
double
Pays
facteur
Sexe
Facteur
où (Pays, Année, Age, Sexe) sert de clé primaire , qx désigne le quotient de mortalité à Age pour Année et Genre dans Pays tandis que qx_ref_year indique le quotient de mortalité à Age pour l’argument reference_year. dans le pays pour le sexe.
ratio_mortality_rates <- function(df,reference_year, target_year){
life_table_target_y <- df[df$Year %in% target_year,]
life_table_1 <- select(life_table_target_y,Year,Age,qx,ex,Country,Gender)
names(life_table_1) <- c('Year','Age','qx','qx.ref_year','Country','Gender')
life_table_ref_year <-df[(df$Year==reference_year),]
life_table_ref_year <- select(life_table_ref_year,Year,Age,qx,Country,Gender)
for(i in 1: nrow(life_table_1)){
if(life_table_1[i,1]==reference_year){
life_table_1[i,4] <- life_table_1[i,3]
}
else {
life_table_2 <- life_table_ref_year[(life_table_ref_year$Age==as.numeric(life_table_1[i,2])) & (life_table_ref_year$Country==as.character(life_table_1[i,5])) & life_table_ref_year$Gender==as.character(life_table_1[i,6]),]
life_table_1[i,4] <- life_table_2[1,3]
}
}
return (life_table_1)
}
life_table_1<- ratio_mortality_rates(life_table,1946,seq(1946,2016,10))
head(life_table_1)
Dessinez des graphiques affichant le rapport \(q_{x,t}/q_{x, 1946}\) pour les âges \(x \in 1, \ldots, 90\) et l’année \(t\) pour \(t \in 1946, \ldots, 2016\) . et l’année \(t\) pour \(t \in 1946, \ldots, 2016\) où \(q_{x,t}\) est le quotient de mortalité à l’âge \(x\) pendant l’année \(t\) .
Traiter les deux sexes et les deux pays Espagne, Italie, France, Angleterre et Pays de Galles, USA, Suède, Pays-Bas.
Une graphique correctement facetté est suffisant (facet_grid(), facet_wrap()).
Warning: Transformation introduced infinite values in continuous y-axis
Au fil du temps, on peut voir que la courbe du ratio des quotients est de plus en plus basse par rapport aux années précédentes. On peut conclure que le quotient de mortalité diminue avec les années, ce qui pourrait s’expliquer par l’amélioration des conditions de vie. De plus, on peut remarquer que les ratios des quotients de mortalité des hommes sont légèrement au-dessus des femmes.
Tendances
Warning: Transformation introduced infinite values in continuous y-axis
Ce facette témoigne de l’évolution de la mortalité infantile au cours du temps pour les âges 0,1 et 5. Comme vu précédemment, on remarque une diminution du taux de mortalité au fil des années.De plus, la courbe des hommes est presque identique à celle des femmes.
Intéressons-nous à présent aux âges 15-20-40-60. On peut observer, une fois de plus, la diminution du taux de mortalité au travers des années. Cependant, les 2 guerres mondiales entraînent des pics sur les courbes (1914-1918, 1939-1945), en particulier chez les hommes de 15-20 ans.
Réarrangement
Vous pouvez utiliser les fonctions pivot_wider, pivot_longer du package tidyr::.
Le schéma du résultat devrait avoir l’aspect suivant:
Country
factor
Gender
factor
Year
integer
0
double
1
double
2
double
3
double
\(\vdots\)
\(\vdots\)
Espérance de vie
esp_res <- function(v_qx,age){
sum = 0
for ( i in age : 109){
pro = 1
for (j in age : i){
m = v_qx[j]/(1-(v_qx[j]/2))
pro = pro * (1-m)
}
sum = sum + pro
}
return(as.numeric(sum))
}
tab_esp_res <- function(df){
df %>%
select(Country,Gender,Year,Age,qx) %>%
pivot_wider(names_from = Age, values_from = qx) -> df
for(i in 1:nrow(df)){
v_qx <- df[i,4:113]
v_qx <- as.numeric(v_qx)
for(j in 4:113){
df[i,j] = esp_res(v_qx,j-3)
}
}
df = pivot_longer(df,cols = -c(Country,Gender,Year), names_to = "Age", values_to ="Res_lex")
return(df)
}
life_table_res_lex <- tab_esp_res(life_table)
head(life_table_res_lex)
Warning: Ignoring unknown aesthetics: Group
PCA et SVD sur les tables de log-mortalité
Warning: ggrepel: 107 unlabeled data points (too many overlaps). Consider increasing max.overlaps
Warning: ggrepel: 13 unlabeled data points (too many overlaps). Consider increasing max.overlaps
Warning: ggrepel: 104 unlabeled data points (too many overlaps). Consider increasing max.overlaps
Warning: ggrepel: 7 unlabeled data points (too many overlaps). Consider increasing max.overlaps
Warning: ggrepel: 103 unlabeled data points (too many overlaps). Consider increasing max.overlaps
Warning: ggrepel: 63 unlabeled data points (too many overlaps). Consider increasing max.overlaps
Warning: ggrepel: 108 unlabeled data points (too many overlaps). Consider increasing max.overlaps
Warning: ggrepel: 36 unlabeled data points (too many overlaps). Consider increasing max.overlaps
Warning: ggrepel: 102 unlabeled data points (too many overlaps). Consider increasing max.overlaps
On peut constater que dans tous les screeplots, la première composante principale explique plus de 93 % de la variance. Pour l’ACP centrée et réduite, il faut garder les 2 premières composantes principales, car elles représentent 96.2 % de la variance expliquée. Ensuite, pour le cas d’une ACP centrée et non réduite, il faut également garder les 2 premières composantes principales, car elles représentent 96.5 % de la variance expliquée.Enfin, pour les ACP non centrée et réduite et non centrée et non réduite, on ne garde que la première composante, car elle représente dans les deux cas 99.9 % de la variance expliquée. Autrement dit, 99.9 % de l’information (variance) est contenue dans les données de la première composante principale.
Sur les deux premiers cercles de corrélation (centré réduit, centré non réduit) on remarque que les variables 0,1,…,109, qui correspondent aux âges sont corrélées négativement à la première composante principale et sont corrélées entre elles. De plus, on constate qu’elles sont très proches du cercle de corrélations donc elles sont bien représentées. Concernant les 2 derniers cercles de corrélations(non centré et réduit, non centré et non réduit), les flèches sont de longueur supérieure à 1, ce qui est normal, car les données ne sont pas centrées. De plus, on remarque sur ces deux cercles que les âges sont corrélés sur les deux composantes principales.
Tout d’abord, les individus correspondent dans notre étude aux années et les variables 0,1,…,109 correspondent aux âges. Un individu qui se trouve du même côté d’une variable donnée a une valeur élevée pour cette variable et un individu qui se trouve dans le côté opposé d’une variable donnée a une faible valeur pour cette variable.
Dans les 2 premiers biplots, on constate que pratiquement la moitié des individus se trouvent du même côté que ceux des variables. Tandis que dans le dernier biplot, tous les individus se trouvent du coté opposé à ceux des variables. Puis, sur le biplot de l’ACP non centrée et réduite, on ne voit plus les individus.
Les bâtons sont proportionnels aux carrés des valeurs singulières normalisées par la somme des carrés des valeurs singulières. Si l’on ne centre pas nos données, nos données seront trop réduites, il faut alors les centrer. En effet, pour la première composante principale, les bâtons rose et vert représentent pratiquement 100 % et plus de 85 % de la part de l’inertie totale expliquée par la première composante. On peut alors projeter nos données sur une dimension et on perdra très peu d’information. Cependant, en faisant cela, nous réduisons beaucoup trop nos données.
On constate que si l’on centre et que l’on normalise ou non nos données, on récupère pratiquement 75 % d’informations sur la première composante principale et on récupère également des informations sur la seconde composante principale.
Il faut donc obligatoirement centrer nos données, quant à la normalisation, elle reste optionnelle.
Modèle Lee-Carter pour la mortalité aux États-Unis
Au cours du siècle dernier, aux États-Unis et en Europe occidentale, les quotients de mortalité à tous les âges ont présenté une tendance générale à la baisse. Cette tendance à la baisse n’a pas toujours été homogène entre les âges.
Le modèle de Lee-Carter a été conçu pour modéliser et prévoir l’évolution du quotient log-mortalité. l’évolution des quotients de mortalité logarithmique pour les États-Unis au cours du XXe siècle.
Soit \(A_{x,t}\) le logarithme du quotient de mortalité à l’âge \(x\) pendant l’année \(t\in T\) . pour une population donnée (définie par le sexe et le pays).
Le modèle de Lee-Carter suppose que les quotients de mortalité logarithmiques observés sont échantillonnés selon le modèle suivant \[
A_{x,t} \sim_{\text{indépendant}} a_x + b_x \kappa_t + \epsilon_{x,t}
\] où \((a_x)_x, (b_x)_x\) et \((\kappa_t)_t\) sont des vecteurs inconnus qui satisfont \[
a_x = \frac{1}{|T|}\sum_{t \in T} A_{x,t}\qquad \sum_{t\in T} \kappa_t = 0 \qquad \sum_{x} b_x^2 =1
\] et \(\epsilon_{x,t}\) sont des variables aléatoires i.i.d. gaussiennes.
Application du modèle de Lee-Carter à un pays européen
Le coefficient de mortalité de la france semble en moyenne aligné avec le coefficient de mortalité obtenu par le regréssement linéaire. En effet, ce dernier est un prolongement du coefficient de mortalité 1933 à 1995.
Tracez les prédictions et les observations pour les années \(2000, 2005, 2010, 2015\) .
Prédictions de l’espérance de vie à différents âges
Références
Tables de mortalité et démographie
Human Mortality Database
Tables de mortalité françaises, Jacques Vallin et France Meslé
Modeling and Forecasting U.S. Mortality, R.D.Lee and L.R. Carter, JASA 1992
Les dimensions de la mortalité, S. Ledermann, Jean Breas, Population, 1959
Samuel H. Preston, Patrick Heuveline and Michel Guillot, Demography: Measuring and Modeling Population Processes , Oxford: Blackwell Publishers, 2001, xv + 291 pp.
Graphiques et rapports
Tidyverse
PCA, SVD
Démographie
LS0tDQp0aXRsZTogJ1Byb2pldCAyMDIxOiBEw6ljb21wb3NpdGlvbiBlbiB2YWxldXJzIHNpbmd1bGnDqHJlcyBldCBUYWJsZXMgZGUgbW9ydGFsaXTDqScNCmF1dGhvcjogIkJvdWxhbmdlciwgTmFudGhha3VtYXIgZXQgQmFpIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGZpZ19jYXB0aW9uOiB5ZXMNCiAgICBrZWVwX21kOiB5ZXMNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvYzogeWVzDQogIGh0bWxfbm90ZWJvb2s6DQogICAgY29kZV9mb2xkaW5nOiBub25lDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2M6IHllcw0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCnN1YnRpdGxlOiAnw4ljaMOpYW5jZTogMjAyMS0xMi0wOScNCnBhcmFtczoNCiAgZGF0YXBhdGg6IGh0dHBzOi8vd3d3LmRyb3Bib3guY29tL3MvdG5jaTM4dHFjaHh3aWM2L2Z1bGxfbGlmZV90YWJsZS5SZHM/ZGw9MA0KICBjb3VudHJ5X2NvZGU6IGZyX3QNCiAgY291bnRyeTogRnJhbmNlDQogIHRpbWVjb3Vyc2U6IDE5NDU6MjAxNQ0KICBsYW5ndWFnZTogRnJlbmNoDQotLS0NCg0KIyDDgCByZW5kcmUgKGxpdnJhYmxlcykNCg0KLSAqKjIwMjEtMTItMDk6KiogdW4gZmljaGllciBgbm9tMV9ub20yLlJtZGAgcXVpIHBldXQgw6p0cmUgYHRyaWNvdMOpYCAoa25pdHRlZCkgc291cyBgcnN0dWRpb2AuDQogIC0gVm90cmUgZmljaGllciBkb2l0IMOqdHJlIHRyaWNvdMOpIHNhbnMgZXJyZXVycyBldCBsZSByw6lzdWx0YXQgZG9pdCDDqnRyZSB1biBkb2N1bWVudCBgaHRtbGAgcXVpIHBldXQgw6p0cmUgdmlzdWFsaXPDqSBkYW5zIHVuIG5hdmlnYXRldXIgbW9kZXJuZS4NCiAgLSBMZSBmaWNoaWVyIGRvaXQgY29udGVuaXIgbGUgY29kZSB1dGlsaXPDqSBwb3VyIGNvbnN0cnVpcmUgbGVzIGdyYXBoaXF1ZXMgZXQgbGVzIHLDqXN1bcOpcyBudW3DqXJpcXVlcy4NCiAgLSBMZSBmaWNoaWVyIGRvaXQgY29udGVuaXIgbGUgdGV4dGUgZGUgdm9zIGNvbW1lbnRhaXJlcyAoZW4gYW5nbGFpcyBvdSBlbiBmcmFuw6dhaXMpLg0KICAtIExlcyBjb21tZW50YWlyZXMgZG9pdmVudCDDqnRyZSByw6lkaWfDqXMgYXZlYyBzb2luIGV0IHByw6ljaXNpb24gZXQgZG9pdmVudCDDqnRyZSBjb25jaXMuDQogIC0gTGUgZmljaGllciBgbm9tMV9ub20yLlJtZGAgc2VyYSB0w6lsw6ljaGFyZ8OpIHN1ciBgTW9vZGxlYC4NCi0gKioyMDIxLTEyLTE0OioqIHVuZSBwcsOpc2VudGF0aW9uIG9yYWxlIGRlIDIwIG1pbnV0ZXMgc3VyIGRlcyDDqWzDqW1lbnRzIGV4dHJhaXRzIGRlIHZvdHJlIHByZW1pZXIgbGl2cmFibGUgYG5vbTFfbm9tMi5SbWRgLg0KICAtIExhIHByw6lzZW50YXRpb24gY29uc2lzdGUgZW4gdW4gZXhwb3PDqSBkZSAxMiBtaW51dGVzIGV0IDggbWludXRlcyBkZSBxdWVzdGlvbnMgZXQgcsOpcG9uc2VzLg0KICAtIExhIHByw6lzZW50YXRpb24gZXN0IHNvdXRlbnVlIHBhciBkZXMgZGlhcG9zaXRpdmVzDQogIC0gTGVzIGRpYXBvc2l0aXZlcyBnw6luw6lyw6llcyDDoCBwYXJ0aXIgZGUgYFJtYXJrZG93bmAgZG9pdmVudCDDqnRyZSBwcml2aWzDqWdpw6llcy4gVm91cyBwb3V2ZXogY2hvaXNpciBsZSBmb3JtYXQgcXVlIHZvdXMgcHLDqWbDqXJleiAoYGJpbmJgLCBgeGFyaW5nYW5gLCBgc2xpZHlgLCBgaW9zbGlkZXNgLCAuLi4pDQoNCi0tLQ0KDQojIE9iamVjdGlmcw0KDQpDZSBjYXJuZXQgZGUgbm90ZXMgYSBwb3VyIGJ1dCBkZQ0KDQogIC0gdHJhdmFpbGxlciBhdmVjIGRlcyAqKnRhYmxlcyoqIChgZGF0YS5mcmFtZXNgLCBgdGliYmxlc2AsIGBkYXRhLnRhYmxlc2AsIC4uLikgZW4gdXRpbGlzYW50IGBkcGx5cmAgb3UgdG91dCBhdXRyZSBsYW5nYWdlIGQnaW50ZXJyb2dhdGlvbiAodGVsIHF1ZSBmb3VybmkgcGFyIGV4ZW1wbGUgcGFyIGBkYXRhLnRhYmxlYCkNCiAgLSB2aXN1YWxpc2VyIGRlcyBkb25uw6llcyBkw6ltb2dyYXBoaXF1ZXMgY29tbWUgY2VsbGVzIGZvdXJuaWVzIHBhciBbSHVtYW4gTW9ydGFsaXR5IERhdGFiYXNlIG9yZ2FuaXphdGlvbl0gKGh0dHBzOi8vd3d3Lm1vcnRhbGl0eS5vcmcpLg0KICAtIGwndXRpbGlzYXRpb24gZGUgbCcqKkFDUCoqIGV0IGQnYXV0cmVzIG3DqXRob2RlcyBtYXRyaWNpZWxsZXMgcG91ciBleHBsb3JlciBkZXMgZW5zZW1ibGVzIGRlIGRvbm7DqWVzIG11bHRpdmFyacOpZXMgKGxlcyB0YWJsZXMgZGUgbW9ydGFsaXTDqSBwZXV2ZW50IMOqdHJlIGNvbnNpZMOpcsOpZXMgY29tbWUgZGVzIGVuc2VtYmxlcyBkZSBkb25uw6llcyBtdWx0aXZhcmnDqWVzKS4NCg0KIyBEb25uw6llcyBkZXMgdGFibGVzIGRlIG1vcnRhbGl0w6kgDQoNCkxlcyB0YWJsZXMgZGUgZG9ubsOpZXMgZGUgdmllIG9udCDDqXTDqSB0w6lsw6ljaGFyZ8OpZXMgw6AgcGFydGlyIGRlIFtodHRwczovL3d3dy5tb3J0YWxpdHkub3JnXShodHRwczovL3d3dy5tb3J0YWxpdHkub3JnKS4gRWxsZXMgb250IMOpdMOpIMOpbGFib3LDqWVzIHBvdXIgdm91cyBldCBwZXV2ZW50IMOqdHJlIHTDqWzDqWNoYXJnw6llcyDDoCBwYXJ0aXIgZGUgbCdVUkwgJ2h0dHBzOi8vd3d3LmRyb3Bib3guY29tL3MvdG5jaTM4dHFjaHh3aWM2L2Z1bGxfbGlmZV90YWJsZS5SZHM/ZGw9MCcsIGVucmVnaXN0csOpZXMgZGFucyB2b3RyZSByw6lwZXJ0b2lyZSBkZSB0cmF2YWlsLg0KDQpTaSB2b3VzIGluc3RhbGxleiBldCBjaGFyZ2V6IGxlIHBhcXVldCBbaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2RlbW9ncmFwaHkvaW5kZXguaHRtbF0oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzL2RlbW9ncmFwaHkvaW5kZXguaHRtbCksIHZvdXMgdHJvdXZlcmV6IMOpZ2FsZW1lbnQgZGVzIHRhYmxlcyBkZSBtb3J0YWxpdMOpLg0KDQpOb3VzIMOpdHVkaW9ucyBkZXMgdGFibGVzIGRlIG1vcnRhbGl0w6kgZMOpY3JpdmFudCBkZXMgcGF5cyBkJ0V1cm9wZSBvY2NpZGVudGFsZSAoRnJhbmNlLCBHcmFuZGUtQnJldGFnbmUgLWVuIGZhaXQgQW5nbGV0ZXJyZSBldCBQYXlzIGRlIEdhbGxlcy0sIEl0YWxpZSwgUGF5cy1CYXMsIEVzcGFnbmUgZXQgU3XDqGRlKSBldCBsZXMgw4l0YXRzLVVuaXMuDQoNCk5vdXMgY2hhcmdlb25zIGxlcyB0YWJsZXMgZGUgbW9ydGFsaXTDqSBhbm51ZWxsZXMgcG91ciBsZXMgZmVtbWVzLCBsZXMgaG9tbWVzIGV0IGxhIHBvcHVsYXRpb24gdG90YWxlIChgYm90aGApIGRlcyBkaWZmw6lyZW50cyBwYXlzLg0KDQoNCmBgYHtyLCBlY2hvPUZBTFNFLCBldmFsPUZBTFNFfQ0KIyBmb3IgZGVidWdnaW5nDQojIHBhcmFtcyBzaG91bGQgYmUgaW5pdGlhbGl6ZWQgZnJvbSBZQU1MIGhlYWRlcg0KcGFyYW1zPC0gbGlzdCgNCiAgICB0aW1lY291cnNlPSAxOTQ1OjIwMTUsDQogICAgZGF0YXBhdGg9ICdodHRwczovL3d3dy5kcm9wYm94LmNvbS9zL3RuY2kzOHRxY2h4d2ljNi9mdWxsX2xpZmVfdGFibGUuUmRzP2RsPTAnLA0KICAgIGNvdW50cnlfY29kZT0gJ2ZyX3QnLA0KICAgIGNvdW50cnk9ICdGcmFuY2UnKQ0KYGBgDQoNCmBgYHtyLCBlY2hvPUZBTFNFfQ0KdGltZWNvdXJzZSA8LSBldmFsKHJsYW5nOjpwYXJzZV9leHByKHBhcmFtcyR0aW1lY291cnNlKSkNCmBgYA0KDQpgYGB7ciB0aWR5dmVyc2UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGVjaG89RkFMU0V9DQppZighICdwYWNtYW4nICVpbiUgaW5zdGFsbGVkLnBhY2thZ2VzKClbLDFdKXsNCiAgaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikNCn0NCg0KcGFjbWFuOjpwX2xvYWQodGlkeXZlcnNlKQ0KcGFjbWFuOjpwX2xvYWQocGxvdGx5KQ0KcGFjbWFuOjpwX2xvYWQoZm9yZWFjaCkNCnBhY21hbjo6cF9sb2FkKGl0ZXJhdG9ycykNCnBhY21hbjo6cF9sb2FkKERUKQ0KcGFjbWFuOjpwX2xvYWQoYWRlNCkNCnBhY21hbjo6cF9sb2FkKEZhY3RvTWluZVIpDQpwYWNtYW46OnBfbG9hZChmYWN0b2V4dHJhKQ0KcGFjbWFuOjpwX2xvYWQoRmFjdG9JbnZlc3RpZ2F0ZSkNCnBhY21hbjo6cF9sb2FkKGdnZm9ydGlmeSkNCnBhY21hbjo6cF9sb2FkKHBhdGhsaWJyKQ0KcGFjbWFuOjpwX2xvYWQoZGVtb2dyYXBoeSkNCnBhY21hbjo6cF9sb2FkKGdsdWUpDQoNCmxpYnJhcnkocHVycnIpDQpsaWJyYXJ5KGJyb29tKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShzY2FsZXMpDQpgYGANCg0KYGBge3Igc2V0X2tuaXRyLCBlY2hvPUZBTFNFfQ0Kb2xkX3RoZW1lIDwtdGhlbWVfc2V0KHRoZW1lX2RhcmsoYmFzZV9zaXplPTksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlX2ZhbWlseSA9ICJIZWx2ZXRpY2EiKSkNCg0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGV2YWw9VFJVRSwNCiAgZWNobz1GQUxTRSwNCiAgd2FybmluZyA9IEZBTFNFLA0KICBtZXNzYWdlID0gRkFMU0UsDQogIGNhY2hlID0gVFJVRSwNCiAgYXV0b2RlcCA9IFRSVUUsDQogIHRpZHkgPSBGQUxTRSkNCg0KYGBgDQoNCg0KYGBge3Igc2V0dXBfaXNvX2NvZGVzLCBlY2hvPUZBTFNFfQ0KY291bnRyeV9jb2RlIDwtIGxpc3QoZnJfdD0nRlJBVE5QJywNCiAgICAgICAgICAgICAgICAgICAgIGZyX2M9J0ZSQUNOUCcsDQogICAgICAgICAgICAgICAgICAgICBiZT0nQkVMJywNCiAgICAgICAgICAgICAgICAgICAgIGdiX3Q9J0dCUlRFTlcnLA0KICAgICAgICAgICAgICAgICAgICAgZ2JfYz0nR0JSQ0VOVycsDQogICAgICAgICAgICAgICAgICAgICBubD0nTkxEJywNCiAgICAgICAgICAgICAgICAgICAgIGl0PSdJVEEnLA0KICAgICAgICAgICAgICAgICAgICAgc3dlPSdTV0UnLA0KICAgICAgICAgICAgICAgICAgICAgc3A9J0VTUCcsDQogICAgICAgICAgICAgICAgICAgICB1cz0nVVNBJykNCg0KY291bnRyaWVzIDwtIGMoJ2ZyX3QnLCAgJ2diX3QnLCAgJ25sJywgJ2l0JywgJ3NwJywgJ3N3ZScsICd1cycpDQoNCmNvdW50cnlfbmFtZXMgPC0gbGlzdChmcl90PSdGcmFuY2UnLCAgICAgIyB0b3RhbCBwb3B1bGF0aW9uDQogICAgICAgICAgICAgICAgICAgICBmcl9jPSdGcmFuY2UnLCAgICAgICMgY2l2aWxpYW4gcG9wdWxhdGlvbg0KICAgICAgICAgICAgICAgICAgICAgYmU9J0JlbGdpdW0nLA0KICAgICAgICAgICAgICAgICAgICAgZ2JfdD0nRW5nbGFuZCAmIFdhbGVzJywgICAgIyB0b3RhbCBwb3B1bGF0aW9uDQogICAgICAgICAgICAgICAgICAgICBnYl9jPSdFbmdsYW5kICYgV2FsZXMnLCAgICAjIGNpdmlsaWFuIHBvcHVsYXRpb24NCiAgICAgICAgICAgICAgICAgICAgIG5sPSdOZXRoZXJsYW5kcycsDQogICAgICAgICAgICAgICAgICAgICBpdD0nSXRhbHknLA0KICAgICAgICAgICAgICAgICAgICAgc3dlPSdTd2VkZW4nLA0KICAgICAgICAgICAgICAgICAgICAgc3A9J1NwYWluJywNCiAgICAgICAgICAgICAgICAgICAgIHVzPSdVU0EnKQ0KDQpnZW5kZXJfbmFtZXMgPC0gbGlzdCgnYic9J0JvdGgnLA0KICAgICAgICAgICAgICAgICAgICAgJ2YnPSdGZW1hbGUnLA0KICAgICAgICAgICAgICAgICAgICAgJ20nPSdNYWxlJykNCmBgYA0KDQpUw6lsw6ljaGFyZ2V6IGxlcyBkb25uw6llcyBkZXB1aXMgYHIgcGFyYW1zJGRhdGFwYXRoYCBkYW5zIHZvdHJlIHLDqXBlcnRvaXJlIF9kZSB0cmF2YWlsXyAod29ya2luZyBkaXJlY3RvcnkpLiBFbnJlZ2lzdHJlei1sZXMgc291cyBsZSBub20gZGUgYGZ1bGxfbGlmZV90YWJsZS5SZHNgLiBDaGFyZ2V6LWxlIGVuIG3DqW1vaXJlIGVuIHV0aWxpc2FudCBgcmVhZHI6OnJlYWRfcmRzKClgLg0KDQpgYGB7ciBsb2FkX2xpZmVfdGFibGUsIGVjaG89VFJVRSwgcmVzdWx0cz0nYXNpcyd9DQpmcGF0aCA8LSAnZnVsbF9saWZlX3RhYmxlLlJkcycgICMgb25jZSB5b3UgaGF2ZSBkb3dubG9hZGVkIHRoZSBmaWxlDQoNCmlmICghIGZpbGUuZXhpc3RzKGZwYXRoKSl7DQogIGNhdChnbHVlKCd7ZnBhdGh9IHNob3VsZCBiZSBpbiB3b3JraW5nIGRpcmVjdG9yeSEnKSkNCn0gZWxzZSB7DQogIGxpZmVfdGFibGUgPC0gcmVhZHI6OnJlYWRfcmRzKGZwYXRoKQ0KICBnbGltcHNlKGxpZmVfdGFibGUpDQp9DQpgYGANCg0KVsOpcmlmaWV6IHN1ciBbaHR0cDovL3d3dy5tb3J0YWxpdHkub3JnXShodHRwOi8vd3d3Lm1vcnRhbGl0eS5vcmcpIGxhIHNpZ25pZmljYXRpb24gZGVzIGRpZmbDqXJlbnRlcyBjb2xvbm5lczoNCg0KTGUgZG9jdW1lbnQgW1RhYmxlcyBkZSBtb3J0YWxpdMOpIGZyYW7Dp2Fpc2VzIHBvdXIgbGVzIFhJWGUgZXQgWFhlIHNpw6hjbGVzIGV0IHByb2plY3Rpb25zIHBvdXIgbGUgWFhJZSBzacOoY2xlXShodHRwczovL3d3dy5saWZldGFibGUuZGUvZGF0YS9GUkEvRlJBMDAwMDE4MDYxOTk3Q1kxLnBkZikgY29udGllbnQNCmRlcyBpbmZvcm1hdGlvbnMgZMOpdGFpbGzDqWVzIHN1ciBsYSBjb25zdHJ1Y3Rpb24gZGVzIFRhYmxlcyBkZSBtb3J0YWxpdMOpIHBvdXIgbGEgRnJhbmNlLg0KT24gcGV1dCBlbiBnw6luw6lyYWwgZGlzdGluZ3VlciBkZXV4IHR5cGVzIGRlIFRhYmxlcyBkZSBtb3J0YWxpdMOpIDogbGVzICpUYWJsZXMgZHUgbW9tZW50KiBxdWkNCmNvbnRpZW5uZW50IHBvdXIgY2hhcXVlIGFubsOpZSBjaXZpbGUsIGxlcyBfcmlzcXVlc18gZGUgbW9ydGFsaXTDqSDDoCBkaWZmw6lyZW50cyDDomdlcyBwb3VyIGNldHRlIG3Dqm1lIGFubsOpZSA7IGV0IGxlcyAqVGFibGVzIGRlIGfDqW7DqXJhdGlvbiogcXVpIGNvbnRpZW5uZW50IHBvdXIgdW5lIGFubsOpZSBkZSBuYWlzc2FuY2UgZG9ubsOpZSwgbGVzIF9yaXNxdWVzXyBkZSBtb3J0YWxpdMOpIGF1eHF1ZWxzIHVuIGluZGl2aWR1IG7DqSBhdSBjb3VycyBkZSBjZXR0ZSBhbm7DqWUgYSDDqXTDqSBleHBvc8OpLg0KDQoNCkxlcyB0YWJsZXMgZGUgbW9ydGFsaXTDqSDDqXR1ZGnDqWVzIGRhbnMgY2UgdHJhdmFpbCBzb250IGxlcyAqVGFibGVzIGR1IG1vbWVudCouIEQnYXByw6hzIGxlIGRvY3VtZW50IGRlIFZhbGxpbiBldCBNZXNsw6ksIGwnw6lsYWJvcmF0aW9uIGRlcyB0YWJsZXMgZGUgbW9ydGFsaXTDqSBhIG7DqWNlc3NpdMOpIGRlcyBjaG9peCBldCB1biB0cmF2YWlsIHN1YnN0YW50aWVsIGQnw6lkaXRpb24uDQoNClZvaXIgKGVudHJlIGF1dHJlcykNCg0KLSBwLiAxOSBMZXMgdmFyaWF0aW9ucyBicnV0YWxlcyBkZXMgcXVvdGllbnRzIGRlIG1vcnRhbGl0w6kgw6AgY2VydGFpbnMgw6JnZXMgcG91ciB1bmUgYW5uw6llIGNpdmlsZSBkb25uw6llDQotIEwnZXN0aW1hdGlvbiBkZXMgcXVvdGllbnRzIGRlIG1vcnRhbGl0w6kgYXUgZ3JhbmQgw6JnZS4NCg0KVm9pciBhdXNzaSBsZXMgW3NjaMOpbWFzIGRlIExleGlzXSAoaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGV4aXNfZGlhZ3JhbSkuDQoNCg0KDQotLS0NCg0KDQrDgCBwYXJ0aXIgZGUgbWFpbnRlbmFudCwgbGEgdGFibGUgdW5pdmVyc2VsbGUgZXN0IG5vbW3DqWUgYGxpZmVfdGFibGVgLg0KDQpMZXMgdGFibGVzIGRlIG1vcnRhbGl0w6kgc3VyIGxlc3F1ZWxsZXMgdm91cyBhbGxleiB0cmF2YWlsbGVyIHNvbnQgYXBwZWzDqWVzIF90YWJsZWF1eCBkZSBtb3J0YWxpdMOpIGRlIGwnYW5uw6llXy4NCg0KDQoNCnwgTm9tIGRlIGxhIGNvbG9ubmUgfCBUeXBlIGRlIGNvbG9ubmUgfCBTaWduaWZpY2F0aW9uIHwNCnw6LS0tLS0tLS0tLS0tfDotLS0tLS0tLS0tLS18LS0tLS0tLS0tLXwNCnwgKipBbm7DqWUqKiB8IG5vbWJyZSBlbnRpZXIgfCB8DQp8ICoqQWdlKiogfCBlbnRpZXIgfCDDgmdlICR4JCB8DQp8IG14IHwgZG91YmxlIHwgVGF1eCBkZSBtb3J0YWxpdMOpIGNlbnRyYWwgw6AgbCfDomdlICR4JCA6ICRtX3gkIHwNCnwgX19xeF9fIHwgZG91YmxlIHwgUHJvYmFiaWxpdMOpIGRlIG1vdXJpciBlbnRyZSBsJ8OiZ2UgZGUgJHgkIGV0IGwnw6JnZSBkZSAkeCsxJCAkcV94ID0gXGZyYWN7bV94fXsxKyBtX3gvMn0kIHwgQXggfCBkb3VibGUgfCAkIDUsNSAkLg0KfCBheCB8IGRvdWJsZSB8IDAsNSQgc2F1ZiDDoCBsJ8OiZ2UgMCQgfA0KfCBseCB8IGVudGllciB8IE5vbWJyZSBkZSBwZXJzb25uZXMgZW5jb3JlIGVuIHZpZSDDoCBsJ8OiZ2UgZGUgJHgkIGRhbnMgdW5lIGNvaG9ydGUgZmljdGl2ZSBkZSAkMTAwMDAwJCB8IGR4IHwgZW50aWVyIHwgTm9tYnJlIGRlIHBlcnNvbm5lcyBlbmNvcmUgZW4gdmllIMOgIGwnw6JnZSBkZSAkeCQuDQp8IGR4IHwgaW50ZWdlciB8IE5vbWJyZSBkZSBwZXJzb25uZXMgZMOpY8OpZMOpZXMgZW50cmUgbCfDomdlICR4JCBldCAkeCsxJCBkdXJhbnQgbCdhbm7DqWUgZGFucyBsYSBjb2hvcnRlIGZpY3RpdmUgfA0KfCBMeCB8IGVudGllciB8IE5vbWJyZSBkJ2FubsOpZXMtcGVyc29ubmVzIHbDqWN1ZXMgZW50cmUgbCfDomdlIGRlICR4JCBldCAkeCsxJCwgJExfeCA9IFxlbGxfeCAtIGRfeFx0aW1lcyBhX3gkIGRhbnMgbGEgY29ob3J0ZSBmaWN0aXZlIHwNCnwgVHggfCBlbnRpZXIgfCB8DQp8IGV4IHwgZG91YmxlIHwgRXNww6lyYW5jZSBkZSB2aWUgcsOpc2lkdWVsbGUgw6AgbCfDomdlICR4JCB8DQp8ICoqUGF5cyoqIHwgZmFjdGV1ciB8IFBheXMtQmFzLy4uLiAgICAgICAgfA0KfCAqKlNleGUqKiB8IGZhY3RldXIgfCBGw6ltaW5pbiAvIE1hc2N1bGluIHwgRmVtbWUgLyBIb21tZQ0KDQpWb2lyICBQcmVzdG9uIF9ldCBhbC5fIHBvdXIgbGVzIGTDqXRhaWxzIGV0IGxlcyBleHBsaWNhdGlvbnMuDQoNCg0KDQpgYGB7cn0NCmxpZmVfdGFibGUgPC0gbGlmZV90YWJsZSAlPiUgDQogIGZpbHRlcihHZW5kZXIhPSdCb3RoJykNCmhlYWQobGlmZV90YWJsZSkNCmBgYA0KDQoNCg0KIyBMJ091ZXN0IChkZSBsJ0V1cm9wZSkgZW4gMTk0OA0KDQotIFsgXSBUcmFjZXogbGVzIF9xdW90aWVudHMgZGUgbW9ydGFsaXTDqV8gZGUgdG91cyBsZXMgcGF5cyDDoCB0b3VzIGxlcyDDomdlcyBwb3VyIGwnYW5uw6llIDE5NDguDQoNCmBgYHtyIGZpZy5hc3AgPSAwLjgsIGZpZy53aWR0aCA9IDl9DQpsaWZlX3RhYmxlXzE5NDggPC0gbGlmZV90YWJsZVsobGlmZV90YWJsZSRZZWFyPT0xOTQ4KSxdDQpsaWZlX3RhYmxlXzE5NDggPC0gc2VsZWN0KGxpZmVfdGFibGVfMTk0OCxZZWFyLEFnZSxxeCxDb3VudHJ5LEdlbmRlcikNCiNoZWFkKGxpZmVfdGFibGVfMTk0OCkNCg0KKGdncGxvdChsaWZlX3RhYmxlXzE5NDgpKyBhZXMoeD1BZ2UsIHk9cXgpDQogICtnZW9tX2xpbmUoYWVzKGNvbG9yPUNvdW50cnksIGdyb3VwPUdlbmRlcikpDQogICtsYWJzKHRpdGxlPSdRdW90aWVudCBkZSBtb3J0YWxpdMOpIHBhciBhZ2UnLCB5PSdRdW90aWVudCBkZSBtb3J0YWxpdMOpJykNCiAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQuaXRhbGljIikpDQogICsgZmFjZXRfZ3JpZChDb3VudHJ5fkdlbmRlcikrc2NhbGVfeV9sb2cxMChsYWJlbHM9c2NpZW50aWZpYykNCiAgK3RoZW1lX2J3KCkpJT4lDQogIHBsb3RseTo6Z2dwbG90bHkoaGVpZ2h0ID03MDAsIHdpZHRoPTgwMCkNCmBgYA0KDQotIFsgXSBDb21tZW50YWlyZQ0KDQpPbiBvYnNlcnZlLCBwb3VyIGwnYW5uw6llIDE5NDgsIHF1ZSBsZSBxdW90aWVudCBkZSBtb3J0YWxpdMOpIGNvbW1lbmNlIMOgIHVuIG5pdmVhdSDDqWxldsOpIHB1aXMgZGltaW51ZSBqdXNxdSfDoCBsJ8OiZ2UgZGUgbCdhZG9sZXNjZW5jZSBhdmFudCBkJ2VudHJlcHJlbmRyZSB1bmUgY3JvaXNzYW5jZSBtb25vdG9uZS4gTGUgZ3JhcGhlIHN1aXQgbGEgbcOqbWUgdGVuZGFuY2UgcXVlbCBxdWUgc29pdCBsZSBwYXlzLiBDZXBlbmRhbnQsIGlsIGRpZmbDqHJlIHNlbG9uIGxlIHNleGUuIE9uIHBldXQgb2JzZXJ2ZXIgdW4gcXVvdGllbnQgZGUgbW9ydGFsaXTDqSBsw6lnw6hyZW1lbnQgcGx1cyDDqWxldsOpIGNoZXogbGVzIGhvbW1lcy4NCg0KLSBbIF0gIFRyYWNlciBsZXMgcmFwcG9ydHMgZW50cmUgbGVzIF9xdW90aWVudHMgZGUgbW9ydGFsaXTDqV8gZGVzIHBheXMgZXVyb3DDqWVucyBldCBsZXMgX3F1b3RpZW50cyBkZSBtb3J0YWxpdMOpXyBkZSB0b3VzIGxlcyBwYXlzIMOgIHRvdXMgbGVzIMOiZ2VzIHBvdXIgbCdhbm7DqWUgMTk0OC4NCmxlcyBfcXVvdGllbnRzIGRlIG1vcnRhbGl0w6lfIGRlcyBVU0EgZW4gMTk0OC4NCg0KYGBge3IgZmlnLmFzcCA9IDAuOCwgZmlnLndpZHRoID0gMTB9DQpsaWZlX3RhYmxlXzE5NDhfdXNhPC0gbGlmZV90YWJsZV8xOTQ4W2xpZmVfdGFibGVfMTk0OCRDb3VudHJ5PT0nVVNBJyxdDQojbGlmZV90YWJsZV8xOTQ4X3VzYQ0KDQpsaWZlX3RhYmxlXzE5NDhfcmF0aW88LSBsaWZlX3RhYmxlXzE5NDggJT4lDQogIG11dGF0ZSAoSW5fRXVyb3BlPSBpZl9lbHNlKENvdW50cnkgJWluJSBjKCdGcmFuY2UnLCdJdGFseScsJ1NwYWluJywnRW5nbGFuZCAmIFdhbGVzJywnTmV0aGVybGFuZHMnLCdTd2VkZW4nKSxULEYpICU+JSBhcy5mYWN0b3IoKSxxeF9yYXRpbz0gaWZfZWxzZShJbl9FdXJvcGU9PVQscXgvbGlmZV90YWJsZV8xOTQ4X3VzYSRxeCxxeCkpDQpsaWZlX3RhYmxlXzE5NDhfcmF0aW8gPC0gbGlmZV90YWJsZV8xOTQ4X3JhdGlvW2xpZmVfdGFibGVfMTk0OF9yYXRpbyRJbl9FdXJvcGU9PVQsXQ0KI+KAvGxpZmVfdGFibGVfMTk0OF9yYXRpbw0KDQooZ2dwbG90KGxpZmVfdGFibGVfMTk0OF9yYXRpbykrIGFlcyh4PUFnZSwgeT1xeF9yYXRpbywgZ3JvdXA9R2VuZGVyKQ0KICArZ2VvbV9saW5lKGFlcyhjb2xvcj1Db3VudHJ5KSkNCiAgK2dlb21fcG9pbnQoYWVzKGNvbG9yPUNvdW50cnkpLHNpemU9MC41LHNoYXBlPTE5KQ0KICArIHNjYWxlX2ZpbGxfYnJld2VyKCkNCiAgK2xhYnModGl0bGU9J1JhcHBvcnQgZW50cmUgbGVzIHF1b3RpZW50cyBkZSBtb3J0YWxpdMOpIGRhbnMgbGVzIHBheXMgZXVyb3DDqWVucyBldCBhdXggRXRhdHMtVW5pcyDDoCBcbnRvdXMgbGVzIMOiZ2VzIGVuIDE5NDggJywgeT0nUmF0aW8gZW50cmUgbGVzIHF1b3RpZW50cyBkZSBtb3J0YWxpdMOpJykNCiAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQuaXRhbGljIikpDQogICsgZmFjZXRfZ3JpZChHZW5kZXJ+LikNCiAgK3RoZW1lX2J3KCkpJT4lDQogIHBsb3RseTo6Z2dwbG90bHkoaGVpZ2h0ID00NTAsIHdpZHRoPTgwMCkNCmBgYA0KDQotIFsgXSBDb21tZW50YWlyZQ0KDQpTdXIgY2UgcGxvdGx5IG9uIHBldXQgY29uc3RhdGVyIHF1ZSBkdXJhbnQgbCdhbm7DqWUgMTk0OCwgbCdFc3BhZ25lIGV0IGwnSXRhbGllIHBvc3PDqWRhaWVudCB1biB0YXV4IGRlIG1vcnRhbGl0w6kgYmllbiBzdXDDqXJpZXVyIMOgIGNlbHVpIGRlcyDDiXRhdHMtVW5pcyBldCBkdSByZXN0ZSBkZSBsJ0V1cm9wZS4gQ2UgcmFwcG9ydCBzJ8OpcXVpbGlicmUgw6AgbCfDomdlIGRlIDQwLiBPbiB2b2l0IMOpZ2FsZW1lbnQgcXVlIGxhIGNvdXJiZSBkZXMgZmVtbWVzIGVzdCBzdXDDqXJpZXVyZSDDoCBjZWxsZSBkZXMgaG9tbWVzLg0KTGVzIGF1dHJlcyBwYXlzIHF1YW50IMOgIGV1eCBzb250IGNvbXBhcmFibGVzIGF1IHRhdXggZGVzIFVTQS4NCg0KIyBFdm9sdXRpb24gZGVzIHRhdXggZGUgbW9ydGFsaXTDqSBkZXB1aXMgbGEgc2Vjb25kZSBndWVycmUgbW9uZGlhbGUNCg0KLSBbIF0gVHJhY2VyIGxlcyBfcXVvdGllbnRzIGRlIG1vcnRhbGl0w6lfIChjb2xvbm5lIGBxeGApIHBvdXIgbGVzDQpsZXMgZGV1eCBzZXhlcyBlbiBmb25jdGlvbiBkZSBsJ8OiZ2UgcG91ciBsZXMgYW5uw6llcyBgMTk0NiwgMTk1NiwgLi4uYCBqdXNxdSfDoCBgMjAxNmAgLg0KVXRpbGlzZXogbCdlc3Row6l0aXF1ZSBwb3VyIGRpc3Rpbmd1ZXIgbGVzIGFubsOpZXMuDQoNCi0gWyBdIEZhY2V0dGUgcGFyIGBHZW5kZXJgIGV0IGBDb3VudHJ5YC4NCg0KYGBge3IgZmlnLmFzcCA9IDEsIGZpZy53aWR0aCA9IDh9DQpsaWZlX3RhYmxlXzE5NDZfMjAxNiA8LSBsaWZlX3RhYmxlWyhsaWZlX3RhYmxlJFllYXIgJWluJSBzZXEoMTk0NiwyMDE2LDEwKSksXQ0KDQooZ2dwbG90KGxpZmVfdGFibGVfMTk0Nl8yMDE2KSthZXMoeD1BZ2UsIHk9cXgsZnJhbWU9WWVhciwgR3JvdXA9Q291bnRyeSkNCiAgK2dlb21fbGluZShhZXMoY29sb3I9R2VuZGVyKSkNCiAgK3NjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiQWNjZW50IikNCiAgK2xhYnModGl0bGU9J1F1b3RpZW50IGRlIG1vcnRhbGl0w6kgcGFyIGFnZSBlbiAxOTQ2LCAxOTU2LCAxOTY2LCAxOTc2LCAxOTg2LCAxOTk2LCAyMDA2LDIwMTYnLCB5PSdRdW90aWVudCBkZSBtb3J0YWxpdMOpJykNCiAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQuaXRhbGljIikgKQ0KICArc2NhbGVfeV9sb2cxMChsYWJlbHM9c2NpZW50aWZpYykNCiAgK2ZhY2V0X2dyaWQoLn5Db3VudHJ5KQ0KICArIHRoZW1lX2J3KCkpJT4lDQogIHBsb3RseTo6Z2dwbG90bHkoaGVpZ2h0ID0zNTAsIHdpZHRoPTgwMCkNCmBgYA0KDQotIFsgXSDDiWNyaXZleiB1bmUgZm9uY3Rpb24gYHJhdGlvX21vcnRhbGl0eV9yYXRlc2AgZG9udCBsYSBzaWduYXR1cmUgZXN0DQpgZnVuY3Rpb24oZGYsIHJlZmVyZW5jZV95ZWFyPTE5NDYsIHRhcmdldF95ZWFycz1zZXEoMTk0NiwgMjAxNiwgMTApKWANCnF1aSBwcmVuZCBjb21tZSBlbnRyw6llDQoNCiAgLSB1biB0YWJsZWF1IGRlIGRvbm7DqWVzIGF2ZWMgbGUgbcOqbWUgc2Now6ltYSBxdWUgYGxpZmVfdGFibGVgLA0KICAtIHVuZSBhbm7DqWUgZGUgcsOpZsOpcmVuY2UgYHJlZl95ZWFyYCBldA0KICAtIHVuZSBzw6lxdWVuY2UgZCdhbm7DqWVzIGB0YXJnZXRfeWVhcnNgLg0KDQpldCBxdWkgcmVudm9pZSB1biB0YWJsZWF1IGRlIGRvbm7DqWVzIGF2ZWMgbGUgc2Now6ltYSA6DQoNCg0KfCBOb20gZGUgbGEgY29sb25uZSB8IFR5cGUgZGUgY29sb25uZSB8DQp8Oi0tLS0tLS0tLS0tLXw6LS0tLS0tLS0tLS0tfA0KfCBBbm7DqWUgfCBlbnRpZXIgfA0KfCBBZ2UgfCBlbnRpZXIgfA0KfCBxeCB8IGRvdWJsZSB8DQp8IHF4LnJlZl95ZWFyfCBkb3VibGUgfA0KfCBQYXlzIHwgZmFjdGV1cg0KfCBTZXhlIHwgRmFjdGV1cg0KDQpvw7kgYChQYXlzLCBBbm7DqWUsIEFnZSwgU2V4ZSlgIHNlcnQgZGUgX2Nsw6kgcHJpbWFpcmVfLA0KYHF4YCBkw6lzaWduZSBsZSBxdW90aWVudCBkZSBtb3J0YWxpdMOpIMOgIGBBZ2VgIHBvdXIgYEFubsOpZWAgZXQgYEdlbnJlYCBkYW5zIGBQYXlzYA0KdGFuZGlzIHF1ZSBgcXhfcmVmX3llYXJgIGluZGlxdWUgbGUgcXVvdGllbnQgZGUgbW9ydGFsaXTDqSDDoCBgQWdlYCBwb3VyIGwnYXJndW1lbnQgYHJlZmVyZW5jZV95ZWFyYC4NCmRhbnMgbGUgYHBheXNgIHBvdXIgbGUgYHNleGVgLg0KDQoNCmBgYHtyLCBlY2hvPVRSVUV9DQpyYXRpb19tb3J0YWxpdHlfcmF0ZXMgPC0gZnVuY3Rpb24oZGYscmVmZXJlbmNlX3llYXIsIHRhcmdldF95ZWFyKXsNCiAgbGlmZV90YWJsZV90YXJnZXRfeSA8LSBkZltkZiRZZWFyICVpbiUgdGFyZ2V0X3llYXIsXQ0KICBsaWZlX3RhYmxlXzEgPC0gc2VsZWN0KGxpZmVfdGFibGVfdGFyZ2V0X3ksWWVhcixBZ2UscXgsZXgsQ291bnRyeSxHZW5kZXIpDQogIG5hbWVzKGxpZmVfdGFibGVfMSkgPC0gYygnWWVhcicsJ0FnZScsJ3F4JywncXgucmVmX3llYXInLCdDb3VudHJ5JywnR2VuZGVyJykNCiAgbGlmZV90YWJsZV9yZWZfeWVhciA8LWRmWyhkZiRZZWFyPT1yZWZlcmVuY2VfeWVhciksXQ0KICBsaWZlX3RhYmxlX3JlZl95ZWFyIDwtIHNlbGVjdChsaWZlX3RhYmxlX3JlZl95ZWFyLFllYXIsQWdlLHF4LENvdW50cnksR2VuZGVyKQ0KICBmb3IoaSBpbiAxOiBucm93KGxpZmVfdGFibGVfMSkpew0KICAgIGlmKGxpZmVfdGFibGVfMVtpLDFdPT1yZWZlcmVuY2VfeWVhcil7DQogICAgICBsaWZlX3RhYmxlXzFbaSw0XSA8LSBsaWZlX3RhYmxlXzFbaSwzXQ0KICAgIH0NCiAgICBlbHNlIHsNCiAgICAgICAgbGlmZV90YWJsZV8yIDwtIGxpZmVfdGFibGVfcmVmX3llYXJbKGxpZmVfdGFibGVfcmVmX3llYXIkQWdlPT1hcy5udW1lcmljKGxpZmVfdGFibGVfMVtpLDJdKSkgJiAobGlmZV90YWJsZV9yZWZfeWVhciRDb3VudHJ5PT1hcy5jaGFyYWN0ZXIobGlmZV90YWJsZV8xW2ksNV0pKSAmIGxpZmVfdGFibGVfcmVmX3llYXIkR2VuZGVyPT1hcy5jaGFyYWN0ZXIobGlmZV90YWJsZV8xW2ksNl0pLF0NCiAgICAgIGxpZmVfdGFibGVfMVtpLDRdIDwtIGxpZmVfdGFibGVfMlsxLDNdDQogICAgfQ0KICB9DQogIHJldHVybiAobGlmZV90YWJsZV8xKQ0KfQ0KDQpsaWZlX3RhYmxlXzE8LSByYXRpb19tb3J0YWxpdHlfcmF0ZXMobGlmZV90YWJsZSwxOTQ2LHNlcSgxOTQ2LDIwMTYsMTApKQ0KaGVhZChsaWZlX3RhYmxlXzEpDQpgYGAgIA0KDQotIFsgXSBEZXNzaW5leiBkZXMgZ3JhcGhpcXVlcyBhZmZpY2hhbnQgbGUgcmFwcG9ydCAkcV97eCx0fS9xX3t4LCAxOTQ2fSQgcG91ciBsZXMgw6JnZXMgJHggXGluIDEsIFxsZG90cywgOTAkIGV0IGwnYW5uw6llICR0JCBwb3VyICR0IFxpbiAxOTQ2LCBcbGRvdHMsIDIwMTYkLg0KZXQgbCdhbm7DqWUgJHQkIHBvdXIgJHQgXGluIDE5NDYsIFxsZG90cywgMjAxNiQgb8O5ICRxX3t4LHR9JCBlc3QgbGUgcXVvdGllbnQgZGUgbW9ydGFsaXTDqSDDoCBsJ8OiZ2UgJHgkIHBlbmRhbnQgbCdhbm7DqWUgJHQkLg0KDQogIDEuIFsgXSBUcmFpdGVyIGxlcyBkZXV4IHNleGVzIGV0IGxlcyBkZXV4IHBheXMgYEVzcGFnbmVgLCBgSXRhbGllYCwgYEZyYW5jZWAsIGBBbmdsZXRlcnJlIGV0IFBheXMgZGUgR2FsbGVzYCwgYFVTQWAsIGBTdcOoZGVgLCBgUGF5cy1CYXNgLg0KICAxLiBbIF0gVW5lIGdyYXBoaXF1ZSBjb3JyZWN0ZW1lbnQgZmFjZXR0w6kgZXN0IHN1ZmZpc2FudCAgKGBmYWNldF9ncmlkKClgLCBgZmFjZXRfd3JhcCgpYCkuDQoNCg0KYGBge3IgIGZpZy5hc3AgPSAxLCBmaWcud2lkdGggPSA4fQ0KbGlmZV90YWJsZV8xPC0gcmF0aW9fbW9ydGFsaXR5X3JhdGVzKGxpZmVfdGFibGUsMTk0NixzZXEoMTk0NiwyMDE2LDEwKSkNCg0KbGlmZV90YWJsZV8xIDwtIGxpZmVfdGFibGVfMVsobGlmZV90YWJsZV8xJEFnZSAlaW4lIHNlcSgxLDkwLDEpKSxdDQoNCmxpZmVfdGFibGVfMTwtIGxpZmVfdGFibGVfMSAlPiUNCiAgbXV0YXRlIChSYXRpbz1xeC9xeC5yZWZfeWVhcikNCg0KKGdncGxvdChsaWZlX3RhYmxlXzEpK2Flcyh4PUFnZSwgeT1SYXRpbyxmcmFtZT1ZZWFyLGdyb3VwPUNvdW50cnkpDQogICtnZW9tX2xpbmUoYWVzKGNvbG9yPUdlbmRlcixsaW5ldHlwZT1HZW5kZXIpKQ0KDQogICtzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIkFjY2VudCIpDQogICtsYWJzKHRpdGxlPSdSYXRpbyBkZXMgcXVvdGllbnRzIGRlIG1vcnRhbGl0w6kgcGFyIGFnZScsIHk9J1JhdGlvIGRlcyBxdW90aWVudHMgZGUgbW9ydGFsaXTDqScpDQogICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJib2xkLml0YWxpYyIpICkNCiAgK3NjYWxlX3lfbG9nMTAobGFiZWxzPXNjaWVudGlmaWMpDQogICtmYWNldF9ncmlkKENvdW50cnl+LikNCiAgK3RoZW1lX2J3KCkpICU+JQ0KICBwbG90bHk6OmdncGxvdGx5KGhlaWdodCA9IDY1MCwgd2lkdGg9NzUwKQ0KYGBgDQoNCi0gQ29tbWVudGFpcmUNCg0KQXUgZmlsIGR1IHRlbXBzLCBvbiBwZXV0IHZvaXIgcXVlIGxhIGNvdXJiZSBkdSByYXRpbyBkZXMgcXVvdGllbnRzIGVzdCBkZSBwbHVzIGVuIHBsdXMgYmFzc2UgcGFyIHJhcHBvcnQgYXV4IGFubsOpZXMgcHLDqWPDqWRlbnRlcy4gT24gcGV1dCBjb25jbHVyZSBxdWUgbGUgcXVvdGllbnQgZGUgbW9ydGFsaXTDqSBkaW1pbnVlIGF2ZWMgbGVzIGFubsOpZXMsIGNlIHF1aSBwb3VycmFpdCBzJ2V4cGxpcXVlciBwYXIgbCdhbcOpbGlvcmF0aW9uIGRlcyBjb25kaXRpb25zIGRlIHZpZS4gRGUgcGx1cywgb24gcGV1dCByZW1hcnF1ZXIgcXVlIGxlcyByYXRpb3MgZGVzIHF1b3RpZW50cyBkZSBtb3J0YWxpdMOpIGRlcyBob21tZXMgc29udCBsw6lnw6hyZW1lbnQgYXUtZGVzc3VzIGRlcyBmZW1tZXMuDQoNCg0KIyBUZW5kYW5jZXMNCg0KDQotIFsgXSBUcmFjZXIgbGVzIHF1b3RpZW50cyBkZSBtb3J0YWxpdMOpIGF1eCDDomdlcyAwLCAxLCA1JCBlbiBmb25jdGlvbiBkdSB0ZW1wcy4gRmFjZXR0ZSBwYXIgc2V4ZSBldCBwYXIgcGF5cw0KDQpgYGB7ciBmaWcuYXNwID0gMSwgZmlnLndpZHRoID0gOH0NCmxpZmVfdGFibGVfMF8xXzUgPC0gbGlmZV90YWJsZSAlPiUNCiAgZmlsdGVyKGxpZmVfdGFibGUkQWdlICVpbiUgYygwLDEsNSkgKQ0KDQpwMzwtIChnZ3Bsb3QobGlmZV90YWJsZV8wXzFfNSwgYWVzKHg9WWVhciwgeT1xeCwgZnJhbWU9QWdlLGdyb3VwPUdlbmRlcikpDQorZ2VvbV9saW5lKGFlcyhjb2xvcj1Db3VudHJ5KSkNCiAgK2xhYnModGl0bGU9J1F1b3RpZW50IGRlIG1vcnRhbGl0w6kgcGFyIGFnZScsIHk9J1F1b3RpZW50IGRlIG1vcnRhbGl0w6knKQ0KICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZC5pdGFsaWMiKSkNCiAgKyBmYWNldF9ncmlkKENvdW50cnl+R2VuZGVyKStzY2FsZV95X2xvZzEwKGxhYmVscz1zY2llbnRpZmljKQ0KICArIHRoZW1lX2J3KCkpJT4lDQogIHBsb3RseTo6Z2dwbG90bHkoaGVpZ2h0ID0gNjAwLCB3aWR0aD03NTApDQoNCnAzDQpgYGANCg0KLSBbIF0gQ29tbWVudGFpcmUNCg0KQ2UgZmFjZXR0ZSB0w6ltb2lnbmUgZGUgbCfDqXZvbHV0aW9uIGRlIGxhIG1vcnRhbGl0w6kgaW5mYW50aWxlIGF1IGNvdXJzIGR1IHRlbXBzIHBvdXIgbGVzIMOiZ2VzIDAsMSBldCA1LiBDb21tZSB2dSBwcsOpY8OpZGVtbWVudCwgb24gcmVtYXJxdWUgdW5lIGRpbWludXRpb24gZHUgdGF1eCBkZSBtb3J0YWxpdMOpIGF1IGZpbCBkZXMgYW5uw6llcy5EZSBwbHVzLCBsYSBjb3VyYmUgZGVzIGhvbW1lcyBlc3QgcHJlc3F1ZSBpZGVudGlxdWUgw6AgY2VsbGUgZGVzIGZlbW1lcy4NCg0KDQoNCi0gWyBdIFRyYWNleiBsZXMgcXVvdGllbnRzIGRlIG1vcnRhbGl0w6kgYXV4IMOiZ2VzIGRlICQxNSwgMjAsIDQwLCA2MCQgZW4gZm9uY3Rpb24gZHUgdGVtcHMuIEZhY2V0dGUgcGFyIGBHZW5kZXJgIGV0IGBDb3VudHJ5YC4NCmBgYHtyIGZpZy5hc3AgPSAxLCBmaWcud2lkdGggPSA4fQ0KbGlmZV90YWJsZV8xNV82MCA8LSBsaWZlX3RhYmxlICU+JQ0KICBmaWx0ZXIobGlmZV90YWJsZSRBZ2UlaW4lIGMoMTUsMjAsNDAsNjApKQ0KIA0KcDQ8LSAoZ2dwbG90KGxpZmVfdGFibGVfMTVfNjAsIGFlcyh4PVllYXIsIHk9cXgsIGZyYW1lPUFnZSwgZ3JvdXA9R2VuZGVyKSkNCitnZW9tX2xpbmUoYWVzKGNvbG9yPUNvdW50cnkpKQ0KICArbGFicyh0aXRsZT0nUXVvdGllbnQgZGUgbW9ydGFsaXTDqSBwYXIgYW5uw6llJywgeT0nUXVvdGllbnQgZGUgbW9ydGFsaXTDqScsIHg9J0FubsOpZScpDQogICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJib2xkLml0YWxpYyIpKQ0KICArIGZhY2V0X2dyaWQoQ291bnRyeX5HZW5kZXIpK3NjYWxlX3lfbG9nMTAobGFiZWxzPXNjaWVudGlmaWMpDQogICsgdGhlbWVfYncoKSklPiUNCiAgcGxvdGx5OjpnZ3Bsb3RseShoZWlnaHQgPSA2MDAsIHdpZHRoPTc1MCkNCg0KcDQNCmBgYA0KDQotIFsgXSBDb21tZW50YWlyZQ0KDQpJbnTDqXJlc3NvbnMtbm91cyDDoCBwcsOpc2VudCBhdXggw6JnZXMgMTUtMjAtNDAtNjAuIE9uIHBldXQgb2JzZXJ2ZXIsIHVuZSBmb2lzIGRlIHBsdXMsIGxhIGRpbWludXRpb24gZHUgdGF1eCBkZSBtb3J0YWxpdMOpIGF1IHRyYXZlcnMgZGVzIGFubsOpZXMuIENlcGVuZGFudCwgbGVzIDIgZ3VlcnJlcyBtb25kaWFsZXMgZW50cmHDrm5lbnQgZGVzIHBpY3Mgc3VyIGxlcyBjb3VyYmVzICgxOTE0LTE5MTgsIDE5MzktMTk0NSksIGVuIHBhcnRpY3VsaWVyIGNoZXogbGVzIGhvbW1lcyBkZSAxNS0yMCBhbnMuDQoNCiMgUsOpYXJyYW5nZW1lbnQNCg0KLSBbIF0gQSBwYXJ0aXIgZHUgdGFibGVhdSBkZSBkb25uw6llcyBgbGlmZV90YWJsZWAsIGNhbGN1bGV6IHVuIGF1dHJlIHRhYmxlYXUgZGUgZG9ubsOpZXMgYXBwZWzDqSBgbGlmZV90YWJsZV9waXZvdGAsICBhdmVjIGxlcyBjbMOpcyBwcmltYWlyZXMgYENvdW50cnlgLCBgR2VuZGVyYCBldCBgWWVhcmAsIGF2ZWMgdW5lIGNvbG9ubmUgcG91ciBjaGFxdWUgYEFnZWAgZGUgYDBgIMOgIGAxMTBgLg0KDQpWb3VzIHBvdXZleiB1dGlsaXNlciBsZXMgZm9uY3Rpb25zICBgcGl2b3Rfd2lkZXJgLCBgcGl2b3RfbG9uZ2VyYCBkdSBwYWNrYWdlICBgdGlkeXI6OmAuDQoNCkxlIHNjaMOpbWEgZHUgcsOpc3VsdGF0IGRldnJhaXQgYXZvaXIgbCdhc3BlY3Qgc3VpdmFudDoNCg0KfCBOb20gZGUgY29sb25uZSB8IFR5cGUgICAgfA0KfDotLS0tLS0tLS0tLS18Oi0tLS0tLS0tfA0KfCBDb3VudHJ5ICAgICB8IGZhY3RvciAgfA0KfCBHZW5kZXIgICAgICB8IGZhY3RvciAgfA0KfCBZZWFyICAgICAgICB8IGludGVnZXIgfA0KfCBgMGAgICAgICAgICB8IGRvdWJsZSAgfA0KfCBgMWAgICAgICAgICB8IGRvdWJsZSAgfA0KfCBgMmAgICAgICAgICB8IGRvdWJsZSAgfA0KfCBgM2AgICAgICAgICB8IGRvdWJsZSAgfA0KfCAkXHZkb3RzJCAgICB8ICRcdmRvdHMkfA0KDQpgYGB7cn0NCmxpZmVfdGFibGVfcGl2b3QgPC0gc2VsZWN0KGxpZmVfdGFibGUsQ291bnRyeSxHZW5kZXIsWWVhcixBZ2UscXgpDQpsaWZlX3RhYmxlX3Bpdm90IDwtIGxpZmVfdGFibGVfcGl2b3QgJT4lIA0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tPUFnZSwgdmFsdWVzX2Zyb209cXgpDQpoZWFkKGxpZmVfdGFibGVfcGl2b3QpDQpgYGANCg0KLSBbIF0gw4AgcGFydGlyIGRlICBgbGlmZV90YWJsZV9waXZvdGAgY2FsY3VsZXIgbCdlc3DDqXJhbmNlIGRlIHZpZSDDoCBsYSBuYWlzc2FuY2UgIHBvdXIgY2hhcXVlIGNsw6kgYENvdW50cnksIEdlbmRlcmAgYW5kIGBZZWFyYC4NCg0KYGBge3J9DQpuZXdfdGFiIDwtIGxpZmVfdGFibGUgJT4lDQogIHNlbGVjdChHZW5kZXIsWWVhcixBZ2UsQ291bnRyeSxseCklPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9QWdlLCB2YWx1ZXNfZnJvbSA9IGx4KS0+bGlmZV90YWJsZV9waXZvdDINCg0KbGYxIDwtIHNlbGVjdChsaWZlX3RhYmxlX3Bpdm90MixHZW5kZXIsWWVhcixDb3VudHJ5KQ0KbGYyIDwtIHN1YnNldChsaWZlX3RhYmxlX3Bpdm90Miwgc2VsZWN0ID0gLWMoR2VuZGVyLFllYXIsQ291bnRyeSkpDQplc3BlIDwtIHZlY3RvcigibnVtZXJpYyIsbnJvdyhsZjIpKQ0KZm9yIChsIGluIDE6bnJvdyhsZjIpKQ0Kew0KICBlc3BlW2xdID0gc3VtKGxmMltsLF0pLzEwMDAwMA0KfQ0KDQpuZXdfdGFiMiA8LSBjYmluZChsZjEsZXNwZSkNCmhlYWQobmV3X3RhYjIpDQpgYGANCg0KIyBFc3DDqXJhbmNlIGRlIHZpZQ0KDQotIFsgXSDDiWNyaXJlIHVuZSBmb25jdGlvbiBxdWkgcHJlbmQgZW4gZW50csOpZSB1biB2ZWN0ZXVyIGRlIHF1b3RpZW50cyBkZSBtb3J0YWxpdMOpLCBhaW5zaSBxdSd1biDDomdlLCBldCByZW52b2llIGwnZXNww6lyYW5jZSBkZSB2aWUgcsOpc2lkdWVsbGUgY29ycmVzcG9uZGFudCBhdSB2ZWN0ZXVyIGV0IMOgIGwnw6JnZSBkb25uw6kuDQoNCmBgYHtyLGVjaG89VFJVRX0NCmVzcF9yZXMgPC0gZnVuY3Rpb24odl9xeCxhZ2Upew0KICANCiAgc3VtID0gMA0KICBmb3IgKCBpIGluIGFnZSA6IDEwOSl7DQogICAgcHJvID0gMQ0KICAgIGZvciAoaiBpbiBhZ2UgOiBpKXsNCiAgICAgIG0gPSB2X3F4W2pdLygxLSh2X3F4W2pdLzIpKQ0KICAgICAgcHJvID0gcHJvICogKDEtbSkNCiAgICB9DQogICAgc3VtID0gc3VtICsgcHJvDQogIH0NCiAgcmV0dXJuKGFzLm51bWVyaWMoc3VtKSkNCn0NCmBgYA0KDQoNCi0gWyBdIMOJY3JpdmV6IHVuZSBmb25jdGlvbiBxdWkgcHJlbmQgY29tbWUgZW50csOpZSB1biB0YWJsZWF1IGRlIGRvbm7DqWVzIGF2ZWMgbGUgbcOqbWUgc2Now6ltYSBxdWUgYGxpZmVfdGFibGVgIGV0IHJldG91cm5lIHVuIHRhYmxlYXUgZGUgZG9ubsOpZXMgYXZlYyBsZXMgY29sb25uZXMgYENvdW50cnlgLCBgR2VuZGVyYCwgYFllYXJgLCBgQWdlYCBkw6lmaW5pc3NhbnQgdW5lIGNsw6kgcHJpbWFpcmUgZXQgdW5lIGNvbG9ubmUgYHJlc19sZXhgIGNvbnRlbmFudCBsJ2VzcMOpcmFuY2UgZGUgdmllIHLDqXNpZHVlbGxlIGNvcnJlc3BvbmRhbnQgw6AgbGEgY2zDqSBwcmltYWlyZS4NCg0KYGBge3IsIGVjaG89VFJVRX0NCnRhYl9lc3BfcmVzIDwtIGZ1bmN0aW9uKGRmKXsNCiAgZGYgJT4lDQogICAgc2VsZWN0KENvdW50cnksR2VuZGVyLFllYXIsQWdlLHF4KSAlPiUNCiAgICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gQWdlLCB2YWx1ZXNfZnJvbSA9IHF4KSAtPiBkZg0KICBmb3IoaSBpbiAxOm5yb3coZGYpKXsNCiAgICB2X3F4IDwtIGRmW2ksNDoxMTNdDQogICAgdl9xeCA8LSBhcy5udW1lcmljKHZfcXgpDQogICAgDQogICAgZm9yKGogaW4gNDoxMTMpew0KICAgICAgZGZbaSxqXSA9IGVzcF9yZXModl9xeCxqLTMpDQogICAgfQ0KICB9DQogIGRmID0gcGl2b3RfbG9uZ2VyKGRmLGNvbHMgPSAtYyhDb3VudHJ5LEdlbmRlcixZZWFyKSwgbmFtZXNfdG8gPSAiQWdlIiwgdmFsdWVzX3RvID0iUmVzX2xleCIpDQogIHJldHVybihkZikNCn0NCg0KbGlmZV90YWJsZV9yZXNfbGV4IDwtIHRhYl9lc3BfcmVzKGxpZmVfdGFibGUpDQpoZWFkKGxpZmVfdGFibGVfcmVzX2xleCkNCmBgYA0KDQoNCi0gWyBdIEFmaW4gZGUgY2FsY3VsZXIgbGVzIGVzcMOpcmFuY2VzIGRlIHZpZSByw6lzaWR1ZWxsZXMsIHZvdXMgcG91dmV6IGVudmlzYWdlciBkJ3V0aWxpc2VyIGxlcyBmb25jdGlvbnMgImZlbsOqdHJlIiBgd2luZG93YCBxdWkgcGVybWV0dGVudCBkZSBkw6lmaW5pciBkZXMgZmVuw6p0cmVzIGFwcHJvcHJpw6llcy4gTGUgcGFxdWV0IGBkcGx5cmAgbidvZmZyZSBwYXMgdW5lIHRyw6hzIHJpY2hlIGludGVyZmFjZSAoQVBJKSBwb3VyIGxlcyBmb25jdGlvbnMgImZlbsOqdHJlIiAod2luZG93IGZ1bmN0aW9ucykuIExlIHBhcXVldCBgZGJwbHlyYCBsZSBmYWl0Lg0KDQoNCi0gWyBdIFRyYWNleiBsJ2VzcMOpcmFuY2UgZGUgdmllIHLDqXNpZHVlbGxlIGVuIGZvbmN0aW9uIGRlIGBZZWFyYCBhdXggw6JnZXMgZGUgJDYwJCBldCAkNjUkLiBDcsOpZXIgdW5lDQoNCg0KYGBge3J9DQpsaWZlX3RhYmxlXzYwXzY1IDwtIHNlbGVjdChsaWZlX3RhYmxlX3Jlc19sZXgsWWVhcixBZ2UsR2VuZGVyLENvdW50cnksUmVzX2xleCkNCmxpZmVfdGFibGVfNjBfNjUgPC0gbGlmZV90YWJsZV82MF82NSAlPiUgZmlsdGVyKGxpZmVfdGFibGVfNjBfNjUkQWdlICVpbiUgYyg2MCw2NSkpDQoNCnA1PC0gKGdncGxvdChsaWZlX3RhYmxlXzYwXzY1LCBhZXMoeD1ZZWFyLCB5PVJlc19sZXgsIGZyYW1lPUFnZSkpDQorZ2VvbV9saW5lKCBhZXMoY29sb3I9Q291bnRyeSAsR3JvdXA9R2VuZGVyKSkNCiAgK2xhYnModGl0bGU9IkwnZXNww6lyYW5jZSBkZSB2aWUgcsOpc2lkdWVsbGUgw6AgbCfDomdlIGRlIDYwIGV0IDY1IGFucyIsIHk9ImwnZXNwZXJhbmNlIGRlIHZpZSByw6lzaWR1ZWxsZSIsIHg9J2FubsOpZScpDQogICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJib2xkLml0YWxpYyIpKQ0KICArIGZhY2V0X2dyaWQoQ291bnRyeX5HZW5kZXIpDQogICsgdGhlbWVfYncoKSklPiUNCiAgcGxvdGx5OjpnZ3Bsb3RseShoZWlnaHQgPSA2NTAsIHdpZHRoPTc1MCkNCnA1DQpgYGANCg0KIyBQQ0EgZXQgU1ZEIHN1ciBsZXMgdGFibGVzIGRlIGxvZy1tb3J0YWxpdMOpDQoNCi0gWyBdIENob2lzaXNzZXogdW4gcGF5cywgdW4gc2V4ZSwgdW5lIHBsYWdlIGQnYW5uw6llcyBgMTk0ODoyMDEwYC4NCkV4dHJheWV6IGxlcyBsaWduZXMgY29ycmVzcG9uZGFudGVzIGRlIGBsaWZlX3RhYmxlX3Bpdm90YC4gUHJlbmRyZSBsZXMgX2xvZ2FyaXRobWVzXyBkZXMNCnF1YW90aWVudHMgZGUgbW9ydGFsaXTDqSBldCBlZmZlY3R1ZXogdW5lIGFuYWx5c2UgZW4gY29tcG9zYW50ZXMgcHJpbmNpcGFsZXMuDQrDiXZhbHVleiBsZXMgcsOpc3VsdGF0cyBkZSBsJ0FDUCBhdmVjIGV0IHNhbnMgY2VudHJhZ2UgZXQgbm9ybWFsaXNhdGlvbiBkZXMgY29sb25uZXMuDQoNCg0KDQpgYGB7cn0NCmNvdW50cnkgPC0gIkZyYW5jZSINCmdlbmRlciA8LSAiRmVtYWxlIg0KeWVhciA8LSBzZXEoMTk0OCwyMDEwLDEpDQoNCmxpZmVfdGFibGVfcGNhIDwtIGxpZmVfdGFibGVfcGl2b3QgJT4lIA0KICBmaWx0ZXIobGlmZV90YWJsZV9waXZvdCRDb3VudHJ5PT1jb3VudHJ5LCBsaWZlX3RhYmxlX3Bpdm90JEdlbmRlcj09Z2VuZGVyICxsaWZlX3RhYmxlX3Bpdm90JFllYXIgJWluJSB5ZWFyKSANCg0KDQpsaWZlX3llYXIgPSBsaWZlX3RhYmxlX3BjYSAlPiUgIHNlbGVjdChZZWFyKQ0KbGlmZV9iaXMgPSBjYmluZChsaWZlX3llYXIsIGxpZmVfdGFibGVfcGNhKQ0Kcm93bmFtZXMobGlmZV9iaXMpPSBsaWZlX2Jpc1ssMV0NCg0KbGlmZV90YWJsZV9wY2EgPC1sb2cobGlmZV9iaXNbLC1jKDEsMiwzLDQpXSkNCiNsaWZlX3RhYmxlX3BjYQ0KDQojQUNQIHLDqWR1aXRlIGV0IGNlbnRyw6llIA0KcmVzLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhLHNjYWxlPVQsY2VudGVyID1UKQ0KDQojQUNQIG5vbiByw6lkdWl0ZSBldCBjZW50csOpZQ0KcmVzMi5hY3A8LXByY29tcChsaWZlX3RhYmxlX3BjYSxzY2FsZT1GLGNlbnRlciA9VCkNCg0KI0FDUCByZWR1aXRlIGV0IG5vbiBjZW50csOpZQ0KcmVzMy5hY3A8LXByY29tcChsaWZlX3RhYmxlX3BjYSxzY2FsZT1ULGNlbnRlciA9RikNCg0KI0FDUCBub24gcmVkdWl0ZSBldCBub24gY2VudHLDqWUNCnJlczQuYWNwPC1wcmNvbXAobGlmZV90YWJsZV9wY2Esc2NhbGU9RixjZW50ZXI9RikNCg0KI0NlcmNsZSBkZSBjb3Jyw6lsYXRpb24gcsOpZHVpdGUgZXQgY2VudHLDqWUgDQpmdml6X3BjYV92YXIocmVzLmFjcCwgY29sLnZhciA9ICJibGFjayIsdGl0bGU9IkNlcmNsZSBkZSBjb3Jyw6lsYXRpb24gZCd1bmUgQUNQIGNlbnRyw6llIGV0IHLDqWR1aXRlIixyZXBlbCA9IFRSVUUpDQoNCiNDZXJjbGUgZGUgY29ycsOpbGF0aW9uIG5vbiByw6lkdWl0ZSBldCBjZW50csOpZQ0KejIgPC0gcmVzMi5hY3AkeA0KY2MyIDwtIGNvcihsaWZlX3RhYmxlX3BjYSx6MlssMTpucm93KGxpZmVfdGFibGVfcGNhKV0pDQpzLmNvcmNpcmNsZShjYzIpDQoNCiNDZXJjbGUgZGUgY29ycsOpbGF0aW9uIHJlZHVpdGUgZXQgbm9uIGNlbnRyw6llDQp6MyA8LSByZXMzLmFjcCR4DQpjYzMgPC0gY29yKGxpZmVfdGFibGVfcGNhLHozWywxOm5yb3cobGlmZV90YWJsZV9wY2EpXSkNCnMuY29yY2lyY2xlKGNjMykNCg0KI0NlcmNsZSBkZSBjb3Jyw6lsYXRpb24gbm9uIHJlZHVpdGUgZXQgbm9uIGNlbnRyw6llDQp6NCA8LSByZXM0LmFjcCR4DQpjYzQgPC0gY29yKGxpZmVfdGFibGVfcGNhLHo0WywxOm5yb3cobGlmZV90YWJsZV9wY2EpXSkNCnMuY29yY2lyY2xlKGNjNCkNCg0KI3NjcmVlcGxvdHMNCg0KZnZpel9laWcocmVzLmFjcCwgYWRkbGFiZWxzPVQsIGhqdXN0PS0wLjMsdGl0bGU9IlNjcmVlcGxvdCBkJ3VuZSBBQ1AgY2VudHLDqWUgZXQgcsOpZHVpdGUiKQ0KZnZpel9laWcocmVzMi5hY3AsIGFkZGxhYmVscz1ULCBoanVzdD0tMC4zLHRpdGxlPSJTY3JlZXBsb3QgZCd1bmUgQUNQIGNlbnRyw6llIGV0IG5vbiByw6lkdWl0ZSIpIA0KZnZpel9laWcocmVzMy5hY3AsIGFkZGxhYmVscz1ULCBoanVzdD0tMC4zLHRpdGxlPSJTY3JlZXBsb3QgZCd1bmUgQUNQIG5vbiBjZW50csOpZSBldCByw6lkdWl0ZSIpDQpmdml6X2VpZyhyZXM0LmFjcCwgYWRkbGFiZWxzPVQsIGhqdXN0PS0wLjMsdGl0bGU9IlNjcmVlcGxvdCBkJ3VuZSBBQ1Agbm9uIGNlbnRyw6llIGV0IG5vbiByw6lkdWl0ZSIpDQoNCiMgYmlwbG90cw0KZnZpel9wY2FfYmlwbG90KHJlcy5hY3AsIHJlcGVsID0gVFJVRSwgdGl0bGU9IkJpcGxvdCBkJ3VuZSBBQ1AgY2VudHLDqWUgZXQgcsOpZHVpdGUiKSANCmZ2aXpfcGNhX2JpcGxvdChyZXMyLmFjcCwgcmVwZWwgPSBUUlVFICwgdGl0bGU9IkJpcGxvdCBkJ3VuZSBBQ1AgY2VudHLDqWUgZXQgbm9uIHLDqWR1aXRlIikgDQpmdml6X3BjYV9iaXBsb3QocmVzMy5hY3AsIHJlcGVsID0gVFJVRSwgdGl0bGU9IkJpcGxvdCBkJ3VuZSBBQ1Agbm9uIGNlbnRyw6llIGV0IHLDqWR1aXRlIikgDQpmdml6X3BjYV9iaXBsb3QocmVzNC5hY3AsIHJlcGVsID0gVFJVRSwgdGl0bGU9IkJpcGxvdCBkJ3VuZSBBQ1Agbm9uIGNlbnRyw6llIGV0IG5vbiByw6lkdWl0ZSIpIA0KDQpgYGANCg0KLSBbIF0gQ29tbWVudGV6IGxlKHMpIGdyYXBoZShzKSBkJ2FmZmljaGFnZS4NCg0KT24gcGV1dCBjb25zdGF0ZXIgcXVlIGRhbnMgdG91cyBsZXMgc2NyZWVwbG90cywgbGEgcHJlbWnDqHJlIGNvbXBvc2FudGUgcHJpbmNpcGFsZSBleHBsaXF1ZSBwbHVzIGRlIDkzICUgZGUgbGEgdmFyaWFuY2UuDQpQb3VyIGwnQUNQIGNlbnRyw6llIGV0IHLDqWR1aXRlLCBpbCBmYXV0IGdhcmRlciBsZXMgMiBwcmVtacOocmVzIGNvbXBvc2FudGVzIHByaW5jaXBhbGVzLCBjYXIgZWxsZXMgcmVwcsOpc2VudGVudCA5Ni4yICUgZGUgbGEgdmFyaWFuY2UgZXhwbGlxdcOpZS4gRW5zdWl0ZSwgcG91ciBsZSBjYXMgZCd1bmUgQUNQIGNlbnRyw6llIGV0IG5vbiByw6lkdWl0ZSwgaWwgZmF1dCDDqWdhbGVtZW50IGdhcmRlciBsZXMgMiBwcmVtacOocmVzIGNvbXBvc2FudGVzIHByaW5jaXBhbGVzLCBjYXIgZWxsZXMgcmVwcsOpc2VudGVudCA5Ni41ICUgZGUgbGEgdmFyaWFuY2UgZXhwbGlxdcOpZS5FbmZpbiwgcG91ciBsZXMgQUNQIG5vbiBjZW50csOpZSBldCByw6lkdWl0ZSBldCBub24gY2VudHLDqWUgZXQgbm9uIHLDqWR1aXRlLCBvbiBuZSBnYXJkZSBxdWUgbGEgcHJlbWnDqHJlIGNvbXBvc2FudGUsIGNhciBlbGxlIHJlcHLDqXNlbnRlIGRhbnMgbGVzIGRldXggY2FzIDk5LjkgJSBkZSBsYSB2YXJpYW5jZSBleHBsaXF1w6llLiBBdXRyZW1lbnQgZGl0LCA5OS45ICUgZGUgbCdpbmZvcm1hdGlvbiAodmFyaWFuY2UpIGVzdCBjb250ZW51ZSBkYW5zIGxlcyBkb25uw6llcyBkZSBsYSBwcmVtacOocmUgY29tcG9zYW50ZSBwcmluY2lwYWxlLg0KDQoNCi0gWyBdIENvbW1lbnRlciBsZShzKSBjZXJjbGUocykgZGUgY29ycsOpbGF0aW9uDQoNClN1ciBsZXMgZGV1eCBwcmVtaWVycyBjZXJjbGVzIGRlIGNvcnLDqWxhdGlvbiAoY2VudHLDqSByw6lkdWl0LCBjZW50csOpIG5vbiByw6lkdWl0KSBvbiByZW1hcnF1ZSBxdWUgbGVzIHZhcmlhYmxlcyAwLDEsLi4uLDEwOSwgcXVpIGNvcnJlc3BvbmRlbnQgYXV4IMOiZ2VzIHNvbnQgY29ycsOpbMOpZXMgbsOpZ2F0aXZlbWVudCDDoCBsYSBwcmVtacOocmUgY29tcG9zYW50ZSBwcmluY2lwYWxlIGV0IHNvbnQgY29ycsOpbMOpZXMgZW50cmUgZWxsZXMuIERlIHBsdXMsIG9uIGNvbnN0YXRlIHF1J2VsbGVzIHNvbnQgdHLDqHMgcHJvY2hlcyBkdSBjZXJjbGUgZGUgY29ycsOpbGF0aW9ucyBkb25jIGVsbGVzIHNvbnQgYmllbiByZXByw6lzZW50w6llcy4NCkNvbmNlcm5hbnQgbGVzIDIgZGVybmllcnMgY2VyY2xlcyBkZSBjb3Jyw6lsYXRpb25zKG5vbiBjZW50csOpIGV0IHLDqWR1aXQsIG5vbiBjZW50csOpIGV0IG5vbiByw6lkdWl0KSwgbGVzIGZsw6hjaGVzIHNvbnQgZGUgbG9uZ3VldXIgc3Vww6lyaWV1cmUgw6AgMSwgY2UgcXVpIGVzdCBub3JtYWwsIGNhciBsZXMgZG9ubsOpZXMgbmUgc29udCBwYXMgY2VudHLDqWVzLiBEZSBwbHVzLCBvbiByZW1hcnF1ZSBzdXIgY2VzIGRldXggY2VyY2xlcyBxdWUgbGVzIMOiZ2VzIHNvbnQgY29ycsOpbMOpcyBzdXIgbGVzIGRldXggY29tcG9zYW50ZXMgcHJpbmNpcGFsZXMuDQoNCi0gWyBdIENvbW1lbnRleiBsZShzKSBgYmlwbG90KHMpYA0KDQpUb3V0IGQnYWJvcmQsIGxlcyBpbmRpdmlkdXMgY29ycmVzcG9uZGVudCBkYW5zIG5vdHJlIMOpdHVkZSBhdXggYW5uw6llcyBldCBsZXMgdmFyaWFibGVzIDAsMSwuLi4sMTA5IGNvcnJlc3BvbmRlbnQgYXV4IMOiZ2VzLiBVbiBpbmRpdmlkdSBxdWkgc2UgdHJvdXZlIGR1IG3Dqm1lIGPDtHTDqSBk4oCZdW5lIHZhcmlhYmxlIGRvbm7DqWUgYSB1bmUgdmFsZXVyIMOpbGV2w6llIHBvdXIgY2V0dGUgdmFyaWFibGUgZXQgdW4gaW5kaXZpZHUgcXVpIHNlIHRyb3V2ZSBkYW5zIGxlIGPDtHTDqSBvcHBvc8OpIGTigJl1bmUgdmFyaWFibGUgZG9ubsOpZSBhIHVuZSBmYWlibGUgdmFsZXVyIHBvdXIgY2V0dGUgdmFyaWFibGUuDQoNCkRhbnMgbGVzIDIgcHJlbWllcnMgYmlwbG90cywgb24gY29uc3RhdGUgcXVlIHByYXRpcXVlbWVudCBsYSBtb2l0acOpIGRlcyBpbmRpdmlkdXMgc2UgdHJvdXZlbnQgZHUgbcOqbWUgY8O0dMOpIHF1ZSBjZXV4IGRlcyB2YXJpYWJsZXMuIFRhbmRpcyBxdWUgZGFucyBsZSBkZXJuaWVyIGJpcGxvdCwgdG91cyBsZXMgaW5kaXZpZHVzIHNlIHRyb3V2ZW50IGR1IGNvdMOpIG9wcG9zw6kgw6AgY2V1eCBkZXMgdmFyaWFibGVzLiBQdWlzLCBzdXIgbGUgYmlwbG90IGRlIGwnQUNQIG5vbiBjZW50csOpZSBldCByw6lkdWl0ZSwgb24gbmUgdm9pdCBwbHVzIGxlcyBpbmRpdmlkdXMuDQoNCg0KLSBbIF0gQ2hvaXNpc3NleiBsYSBjb21iaW5haXNvbiBkZSBjZW50cmFnZSBldCBkZSBub3JtYWxpc2F0aW9uIHF1aSB2b3VzIHNlbWJsZSBsYSBwbHVzIHBlcnRpbmVudGUuIE1vdGl2ZXogdm90cmUgY2hvaXgNCg0KYGBge3J9DQpkZjwtIGxpZmVfdGFibGVfcGl2b3QgDQpkZl9udW08LSBkcGx5cjo6c2VsZWN0KGRmLC1jKFllYXIsQ291bnRyeSxHZW5kZXIpKQ0KDQpsaXN0X3BjYV9kZiA8LSBtYXAyKC54ID0gcmVwKGMoRkFMU0UsIFRSVUUpLCAyKSwNCiAgICAueSA9IHJlcChjKEZBTFNFLCBUUlVFKSwgYygyLDIpKSwNCiAgICB+IHByY29tcChkZl9udW0sIGNlbnRlcj0gLngsIHNjYWxlLj0ueSwgcmFuaz00KQ0KKQ0KbmFtZXMobGlzdF9wY2FfZGYpIDwtc3RyaW5ncjo6IHN0cl9jKCJwY2FfbGlmZSIsDQogICAgYygiIiwgImMiLCAicyIsICJjX3MiKSwNCiAgICBzZXAgPSAiXyIpDQpkID0gIDExMCAgICAgICAgICAgICANCmNvbmZpZ19wYXJhbSA8LSBhcy52ZWN0b3Iob3V0ZXIoYygiXyIsICJjZW50ZXIiKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCJfIiwgInNjYWxlIiksIEZVTj1wYXN0ZSkpICU+JQ0KIHJlcChjKGQsZCxkLGQpKQ0KDQpsaXN0X3BjYV9kZiAlPiUNCiAgbWFwX2Rmcih+IHRpZHkoLiwgbWF0cml4PSJwY3MiKSkgJT4lDQogIG11dGF0ZShQYXJhbWV0ZXIgPSBjb25maWdfcGFyYW0pIC0+IGRmX3BjYV9jX3MNCiANCmRmX3BjYV9jX3MgICU+JQ0KICBmaWx0ZXIoUEMgPCA1KSAlPiUNCiAgZ2dwbG90KCkgKw0KICBhZXMoeD1QQywgeSA9IHBlcmNlbnQsIGZpbGwgPSBQYXJhbWV0ZXIpICsNCiAgZ2VvbV9jb2wocG9zaXRpb24gPSAiZG9kZ2UiKSArDQogIHRoZW1lX2J3KCkgKw0KICBsYWJzKHRpdGxlID0gIkxpZmVfdGFibGUgOiBzaGFyZSBvZiBpbmVydGlhIHBlciBQQyIsDQogICAgICAgc3VidGl0bGUgPSAiQ2VudGVyaW5nLCBzY2FsaW5nIG9yIG5vdCIpDQpgYGANCg0KTGVzIGLDonRvbnMgc29udCBwcm9wb3J0aW9ubmVscyBhdXggY2FycsOpcyBkZXMgdmFsZXVycyBzaW5ndWxpw6hyZXMgbm9ybWFsaXPDqWVzIHBhciBsYSBzb21tZSBkZXMgY2FycsOpcyBkZXMgdmFsZXVycyBzaW5ndWxpw6hyZXMuDQpTaSBsJ29uIG5lIGNlbnRyZSBwYXMgbm9zIGRvbm7DqWVzLCBub3MgZG9ubsOpZXMgc2Vyb250IHRyb3AgcsOpZHVpdGVzLCBpbCBmYXV0IGFsb3JzIGxlcyBjZW50cmVyLiBFbiBlZmZldCwgcG91ciBsYSBwcmVtacOocmUgY29tcG9zYW50ZSBwcmluY2lwYWxlLCBsZXMgYsOidG9ucyByb3NlIGV0IHZlcnQgcmVwcsOpc2VudGVudCBwcmF0aXF1ZW1lbnQgMTAwICUgZXQgcGx1cyBkZSA4NSAlIGRlIGxhIHBhcnQgZGUgbCdpbmVydGllIHRvdGFsZSBleHBsaXF1w6llIHBhciBsYSBwcmVtacOocmUgY29tcG9zYW50ZS4gT24gcGV1dCBhbG9ycyBwcm9qZXRlciBub3MgZG9ubsOpZXMgc3VyIHVuZSBkaW1lbnNpb24gZXQgb24gcGVyZHJhIHRyw6hzIHBldSBkJ2luZm9ybWF0aW9uLiBDZXBlbmRhbnQsIGVuIGZhaXNhbnQgY2VsYSwgbm91cyByw6lkdWlzb25zIGJlYXVjb3VwIHRyb3Agbm9zIGRvbm7DqWVzLg0KDQpPbiBjb25zdGF0ZSBxdWUgc2kgbCdvbiBjZW50cmUgZXQgcXVlIGwnb24gbm9ybWFsaXNlIG91IG5vbiBub3MgZG9ubsOpZXMsIG9uIHLDqWN1cMOocmUgcHJhdGlxdWVtZW50IDc1ICUgZCdpbmZvcm1hdGlvbnMgc3VyIGxhIHByZW1pw6hyZSBjb21wb3NhbnRlIHByaW5jaXBhbGUgZXQgb24gcsOpY3Vww6hyZSDDqWdhbGVtZW50IGRlcyBpbmZvcm1hdGlvbnMgc3VyIGxhIHNlY29uZGUgY29tcG9zYW50ZSBwcmluY2lwYWxlLg0KDQpJbCBmYXV0IGRvbmMgb2JsaWdhdG9pcmVtZW50IGNlbnRyZXIgbm9zIGRvbm7DqWVzLCBxdWFudCDDoCBsYSBub3JtYWxpc2F0aW9uLCBlbGxlIHJlc3RlIG9wdGlvbm5lbGxlLg0KDQotIFsgXSBFZmZlY3R1ZXogdW5lIEFDUCBzdXIgbCdlbnNlbWJsZSBkZXMgcGF5cyBldCBkZXMgc2V4ZXMgYXZlYyBsYSBjb21iaW5haXNvbiBkZSBjZW50cmFnZSBldCBkZSBtaXNlIMOgIGwnw6ljaGVsbGUgY2hvaXNpZS4NCg0KYGBge3J9DQojIyMjIyMjIyMgRlJBTkNFDQpjb3VudHJ5IDwtICJGcmFuY2UiDQpnZW5kZXIgPC0gIkZlbWFsZSINCnllYXIgPC0gc2VxKDE5NDgsMjAxMCwxKQ0KDQpsaWZlX3RhYmxlX3BjYV9GRiA8LSBsaWZlX3RhYmxlX3Bpdm90ICU+JSANCiAgZmlsdGVyKGxpZmVfdGFibGVfcGl2b3QkQ291bnRyeT09Y291bnRyeSwgbGlmZV90YWJsZV9waXZvdCRHZW5kZXI9PWdlbmRlciAsbGlmZV90YWJsZV9waXZvdCRZZWFyICVpbiUgeWVhcikgDQoNCmxpZmVfeWVhciA9IGxpZmVfdGFibGVfcGNhX0ZGICU+JSAgc2VsZWN0KFllYXIpDQpsaWZlX2JpcyA9IGNiaW5kKGxpZmVfeWVhciwgbGlmZV90YWJsZV9wY2FfRkYpDQpyb3duYW1lcyhsaWZlX2Jpcyk9IGxpZmVfYmlzWywxXQ0KDQpsaWZlX3RhYmxlX3BjYV9GRiA8LWxvZyhsaWZlX2Jpc1ssLWMoMSwyLDMsNCldKQ0KcmVzX0ZGLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhX0ZGLHNjYWxlPVQsY2VudGVyID0gVCkNCg0KDQpjb3VudHJ5IDwtICJGcmFuY2UiDQpnZW5kZXIgPC0gIk1hbGUiDQp5ZWFyIDwtIHNlcSgxOTQ4LDIwMTAsMSkNCg0KbGlmZV90YWJsZV9wY2FfRk0gPC0gbGlmZV90YWJsZV9waXZvdCAlPiUgDQogIGZpbHRlcihsaWZlX3RhYmxlX3Bpdm90JENvdW50cnk9PWNvdW50cnksIGxpZmVfdGFibGVfcGl2b3QkR2VuZGVyPT1nZW5kZXIgLGxpZmVfdGFibGVfcGl2b3QkWWVhciAlaW4lIHllYXIpIA0KDQpsaWZlX3llYXIgPSBsaWZlX3RhYmxlX3BjYV9GTSAlPiUgIHNlbGVjdChZZWFyKQ0KbGlmZV9iaXMgPSBjYmluZChsaWZlX3llYXIsIGxpZmVfdGFibGVfcGNhX0ZNKQ0Kcm93bmFtZXMobGlmZV9iaXMpPSBsaWZlX2Jpc1ssMV0NCg0KbGlmZV90YWJsZV9wY2FfRk0gPC1sb2cobGlmZV9iaXNbLC1jKDEsMiwzLDQpXSkNCnJlc19GTS5hY3A8LXByY29tcChsaWZlX3RhYmxlX3BjYV9GTSxzY2FsZT1ULGNlbnRlciA9IFQpDQoNCiMjIyMjIyMjIyBJVEFMWQ0KDQpjb3VudHJ5IDwtICJJdGFseSINCmdlbmRlciA8LSAiRmVtYWxlIg0KeWVhciA8LSBzZXEoMTk0OCwyMDEwLDEpDQoNCmxpZmVfdGFibGVfcGNhX0lGIDwtIGxpZmVfdGFibGVfcGl2b3QgJT4lIA0KICBmaWx0ZXIobGlmZV90YWJsZV9waXZvdCRDb3VudHJ5PT1jb3VudHJ5LCBsaWZlX3RhYmxlX3Bpdm90JEdlbmRlcj09Z2VuZGVyICxsaWZlX3RhYmxlX3Bpdm90JFllYXIgJWluJSB5ZWFyKSANCg0KbGlmZV95ZWFyID0gbGlmZV90YWJsZV9wY2FfSUYgJT4lICBzZWxlY3QoWWVhcikNCmxpZmVfYmlzID0gY2JpbmQobGlmZV95ZWFyLCBsaWZlX3RhYmxlX3BjYV9JRikNCnJvd25hbWVzKGxpZmVfYmlzKT0gbGlmZV9iaXNbLDFdDQoNCmxpZmVfdGFibGVfcGNhX0lGIDwtbG9nKGxpZmVfYmlzWywtYygxLDIsMyw0KV0pDQpyZXNfSUYuYWNwPC1wcmNvbXAobGlmZV90YWJsZV9wY2FfSUYsc2NhbGU9VCxjZW50ZXIgPSBUKQ0KDQpjb3VudHJ5IDwtICJJdGFseSINCmdlbmRlciA8LSAiTWFsZSINCnllYXIgPC0gc2VxKDE5NDgsMjAxMCwxKQ0KDQpsaWZlX3RhYmxlX3BjYV9JTSA8LSBsaWZlX3RhYmxlX3Bpdm90ICU+JSANCiAgZmlsdGVyKGxpZmVfdGFibGVfcGl2b3QkQ291bnRyeT09Y291bnRyeSwgbGlmZV90YWJsZV9waXZvdCRHZW5kZXI9PWdlbmRlciAsbGlmZV90YWJsZV9waXZvdCRZZWFyICVpbiUgeWVhcikgDQoNCmxpZmVfeWVhciA9IGxpZmVfdGFibGVfcGNhX0lNICU+JSAgc2VsZWN0KFllYXIpDQpsaWZlX2JpcyA9IGNiaW5kKGxpZmVfeWVhciwgbGlmZV90YWJsZV9wY2FfSU0pDQpyb3duYW1lcyhsaWZlX2Jpcyk9IGxpZmVfYmlzWywxXQ0KDQpsaWZlX3RhYmxlX3BjYV9JTSA8LWxvZyhsaWZlX2Jpc1ssLWMoMSwyLDMsNCldKQ0KcmVzX0lNLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhX0lNLHNjYWxlPVQsY2VudGVyID0gVCkNCg0KDQojIyMjIyMjIyMgU1BBSU4NCg0KY291bnRyeSA8LSAiU3BhaW4iDQpnZW5kZXIgPC0gIkZlbWFsZSINCnllYXIgPC0gc2VxKDE5NDgsMjAxMCwxKQ0KDQpsaWZlX3RhYmxlX3BjYV9TRiA8LSBsaWZlX3RhYmxlX3Bpdm90ICU+JSANCiAgZmlsdGVyKGxpZmVfdGFibGVfcGl2b3QkQ291bnRyeT09Y291bnRyeSwgbGlmZV90YWJsZV9waXZvdCRHZW5kZXI9PWdlbmRlciAsbGlmZV90YWJsZV9waXZvdCRZZWFyICVpbiUgeWVhcikgDQoNCmxpZmVfeWVhciA9IGxpZmVfdGFibGVfcGNhX1NGICU+JSAgc2VsZWN0KFllYXIpDQpsaWZlX2JpcyA9IGNiaW5kKGxpZmVfeWVhciwgbGlmZV90YWJsZV9wY2FfU0YpDQpyb3duYW1lcyhsaWZlX2Jpcyk9IGxpZmVfYmlzWywxXQ0KDQpsaWZlX3RhYmxlX3BjYV9TRiA8LWxvZyhsaWZlX2Jpc1ssLWMoMSwyLDMsNCldKQ0KcmVzX1NGLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhX1NGLHNjYWxlPVQsY2VudGVyID0gVCkNCg0KDQpjb3VudHJ5IDwtICJTcGFpbiINCmdlbmRlciA8LSAiTWFsZSINCnllYXIgPC0gc2VxKDE5NDgsMjAxMCwxKQ0KDQpsaWZlX3RhYmxlX3BjYV9TTSA8LSBsaWZlX3RhYmxlX3Bpdm90ICU+JSANCiAgZmlsdGVyKGxpZmVfdGFibGVfcGl2b3QkQ291bnRyeT09Y291bnRyeSwgbGlmZV90YWJsZV9waXZvdCRHZW5kZXI9PWdlbmRlciAsbGlmZV90YWJsZV9waXZvdCRZZWFyICVpbiUgeWVhcikgDQoNCmxpZmVfeWVhciA9IGxpZmVfdGFibGVfcGNhX1NNICU+JSAgc2VsZWN0KFllYXIpDQpsaWZlX2JpcyA9IGNiaW5kKGxpZmVfeWVhciwgbGlmZV90YWJsZV9wY2FfU00pDQpyb3duYW1lcyhsaWZlX2Jpcyk9IGxpZmVfYmlzWywxXQ0KDQpsaWZlX3RhYmxlX3BjYV9TTSA8LWxvZyhsaWZlX2Jpc1ssLWMoMSwyLDMsNCldKQ0KcmVzX1NNLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhX1NNLHNjYWxlPVQsY2VudGVyID0gVCkNCg0KIyMjIyMjIyMjIEVuZ2xhbmQgJiBXYWxlcw0KDQpjb3VudHJ5IDwtICJFbmdsYW5kICYgV2FsZXMiDQpnZW5kZXIgPC0gIkZlbWFsZSINCnllYXIgPC0gc2VxKDE5NDgsMjAxMCwxKQ0KDQpsaWZlX3RhYmxlX3BjYV9FV0YgPC0gbGlmZV90YWJsZV9waXZvdCAlPiUgDQogIGZpbHRlcihsaWZlX3RhYmxlX3Bpdm90JENvdW50cnk9PWNvdW50cnksIGxpZmVfdGFibGVfcGl2b3QkR2VuZGVyPT1nZW5kZXIgLGxpZmVfdGFibGVfcGl2b3QkWWVhciAlaW4lIHllYXIpIA0KDQpsaWZlX3llYXIgPSBsaWZlX3RhYmxlX3BjYV9FV0YgJT4lICBzZWxlY3QoWWVhcikNCmxpZmVfYmlzID0gY2JpbmQobGlmZV95ZWFyLCBsaWZlX3RhYmxlX3BjYV9FV0YpDQpyb3duYW1lcyhsaWZlX2Jpcyk9IGxpZmVfYmlzWywxXQ0KDQpsaWZlX3RhYmxlX3BjYV9FV0YgPC1sb2cobGlmZV9iaXNbLC1jKDEsMiwzLDQpXSkNCnJlc19FV0YuYWNwPC1wcmNvbXAobGlmZV90YWJsZV9wY2FfRVdGLHNjYWxlPVQsY2VudGVyID0gVCkNCg0KDQpjb3VudHJ5IDwtICJFbmdsYW5kICYgV2FsZXMiDQpnZW5kZXIgPC0gIk1hbGUiDQp5ZWFyIDwtIHNlcSgxOTQ4LDIwMTAsMSkNCg0KbGlmZV90YWJsZV9wY2FfRVdNIDwtIGxpZmVfdGFibGVfcGl2b3QgJT4lIA0KICBmaWx0ZXIobGlmZV90YWJsZV9waXZvdCRDb3VudHJ5PT1jb3VudHJ5LCBsaWZlX3RhYmxlX3Bpdm90JEdlbmRlcj09Z2VuZGVyICxsaWZlX3RhYmxlX3Bpdm90JFllYXIgJWluJSB5ZWFyKSANCg0KbGlmZV95ZWFyID0gbGlmZV90YWJsZV9wY2FfRVdNICU+JSAgc2VsZWN0KFllYXIpDQpsaWZlX2JpcyA9IGNiaW5kKGxpZmVfeWVhciwgbGlmZV90YWJsZV9wY2FfRVdNKQ0Kcm93bmFtZXMobGlmZV9iaXMpPSBsaWZlX2Jpc1ssMV0NCg0KbGlmZV90YWJsZV9wY2FfRVdNIDwtbG9nKGxpZmVfYmlzWywtYygxLDIsMyw0KV0pDQpyZXNfRVdNLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhX0VXTSxzY2FsZT1ULGNlbnRlciA9IFQpDQoNCg0KIyMjIyMjIyMjIFN3ZWRlbg0KDQpjb3VudHJ5IDwtICJTd2VkZW4iDQpnZW5kZXIgPC0gIkZlbWFsZSINCnllYXIgPC0gc2VxKDE5NDgsMjAxMCwxKQ0KDQpsaWZlX3RhYmxlX3BjYV9TV0YgPC0gbGlmZV90YWJsZV9waXZvdCAlPiUgDQogIGZpbHRlcihsaWZlX3RhYmxlX3Bpdm90JENvdW50cnk9PWNvdW50cnksIGxpZmVfdGFibGVfcGl2b3QkR2VuZGVyPT1nZW5kZXIgLGxpZmVfdGFibGVfcGl2b3QkWWVhciAlaW4lIHllYXIpIA0KDQpsaWZlX3llYXIgPSBsaWZlX3RhYmxlX3BjYV9TV0YgJT4lICBzZWxlY3QoWWVhcikNCmxpZmVfYmlzID0gY2JpbmQobGlmZV95ZWFyLCBsaWZlX3RhYmxlX3BjYV9TV0YpDQpyb3duYW1lcyhsaWZlX2Jpcyk9IGxpZmVfYmlzWywxXQ0KDQpsaWZlX3RhYmxlX3BjYV9TV0YgPC1sb2cobGlmZV9iaXNbLC1jKDEsMiwzLDQpXSkNCiNyZXNfU1dGLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhX1NXRixzY2FsZT1ULGNlbnRlciA9IFQpDQoNCg0KY291bnRyeSA8LSAiU3dlZGVuIg0KZ2VuZGVyIDwtICJNYWxlIg0KeWVhciA8LSBzZXEoMTk0OCwyMDEwLDEpDQoNCmxpZmVfdGFibGVfcGNhX1NXTSA8LSBsaWZlX3RhYmxlX3Bpdm90ICU+JSANCiAgZmlsdGVyKGxpZmVfdGFibGVfcGl2b3QkQ291bnRyeT09Y291bnRyeSwgbGlmZV90YWJsZV9waXZvdCRHZW5kZXI9PWdlbmRlciAsbGlmZV90YWJsZV9waXZvdCRZZWFyICVpbiUgeWVhcikgDQoNCmxpZmVfeWVhciA9IGxpZmVfdGFibGVfcGNhX1NXTSAlPiUgIHNlbGVjdChZZWFyKQ0KbGlmZV9iaXMgPSBjYmluZChsaWZlX3llYXIsIGxpZmVfdGFibGVfcGNhX1NXTSkNCnJvd25hbWVzKGxpZmVfYmlzKT0gbGlmZV9iaXNbLDFdDQoNCmxpZmVfdGFibGVfcGNhX1NXTSA8LWxvZyhsaWZlX2Jpc1ssLWMoMSwyLDMsNCldKQ0KcmVzX1NXTS5hY3A8LXByY29tcChsaWZlX3RhYmxlX3BjYV9TV00sc2NhbGU9VCxjZW50ZXIgPSBUKQ0KDQoNCiMjIyMjIyMjIyBVU0ENCg0KY291bnRyeSA8LSAiVVNBIg0KZ2VuZGVyIDwtICJGZW1hbGUiDQp5ZWFyIDwtIHNlcSgxOTQ4LDIwMTAsMSkNCg0KbGlmZV90YWJsZV9wY2FfVVNBRiA8LSBsaWZlX3RhYmxlX3Bpdm90ICU+JSANCiAgZmlsdGVyKGxpZmVfdGFibGVfcGl2b3QkQ291bnRyeT09Y291bnRyeSwgbGlmZV90YWJsZV9waXZvdCRHZW5kZXI9PWdlbmRlciAsbGlmZV90YWJsZV9waXZvdCRZZWFyICVpbiUgeWVhcikgDQoNCmxpZmVfeWVhciA9IGxpZmVfdGFibGVfcGNhX1VTQUYgJT4lICBzZWxlY3QoWWVhcikNCmxpZmVfYmlzID0gY2JpbmQobGlmZV95ZWFyLCBsaWZlX3RhYmxlX3BjYV9VU0FGKQ0Kcm93bmFtZXMobGlmZV9iaXMpPSBsaWZlX2Jpc1ssMV0NCg0KbGlmZV90YWJsZV9wY2FfVVNBRiA8LWxvZyhsaWZlX2Jpc1ssLWMoMSwyLDMsNCldKQ0KcmVzX1VTQUYuYWNwPC1wcmNvbXAobGlmZV90YWJsZV9wY2FfVVNBRixzY2FsZT1ULGNlbnRlciA9IFQpDQoNCg0KY291bnRyeSA8LSAiVVNBIg0KZ2VuZGVyIDwtICJNYWxlIg0KeWVhciA8LSBzZXEoMTk0OCwyMDEwLDEpDQoNCmxpZmVfdGFibGVfcGNhX05NIDwtIGxpZmVfdGFibGVfcGl2b3QgJT4lIA0KICBmaWx0ZXIobGlmZV90YWJsZV9waXZvdCRDb3VudHJ5PT1jb3VudHJ5LCBsaWZlX3RhYmxlX3Bpdm90JEdlbmRlcj09Z2VuZGVyICxsaWZlX3RhYmxlX3Bpdm90JFllYXIgJWluJSB5ZWFyKSANCg0KbGlmZV95ZWFyID0gbGlmZV90YWJsZV9wY2FfTk0gJT4lICBzZWxlY3QoWWVhcikNCmxpZmVfYmlzID0gY2JpbmQobGlmZV95ZWFyLCBsaWZlX3RhYmxlX3BjYV9OTSkNCnJvd25hbWVzKGxpZmVfYmlzKT0gbGlmZV9iaXNbLDFdDQoNCmxpZmVfdGFibGVfcGNhX05NIDwtbG9nKGxpZmVfYmlzWywtYygxLDIsMyw0KV0pDQpyZXNfTk0uYWNwPC1wcmNvbXAobGlmZV90YWJsZV9wY2FfTk0sc2NhbGU9VCxjZW50ZXIgPSBUKQ0KDQoNCiMjIyMjIyMjIyBORVRIRVJMQU5Ecw0KDQpjb3VudHJ5IDwtICJOZXRoZXJsYW5kcyINCmdlbmRlciA8LSAiRmVtYWxlIg0KeWVhciA8LSBzZXEoMTk0OCwyMDEwLDEpDQoNCmxpZmVfdGFibGVfcGNhX05GIDwtIGxpZmVfdGFibGVfcGl2b3QgJT4lIA0KICBmaWx0ZXIobGlmZV90YWJsZV9waXZvdCRDb3VudHJ5PT1jb3VudHJ5LCBsaWZlX3RhYmxlX3Bpdm90JEdlbmRlcj09Z2VuZGVyICxsaWZlX3RhYmxlX3Bpdm90JFllYXIgJWluJSB5ZWFyKSANCg0KbGlmZV95ZWFyID0gbGlmZV90YWJsZV9wY2FfTkYgJT4lICBzZWxlY3QoWWVhcikNCmxpZmVfYmlzID0gY2JpbmQobGlmZV95ZWFyLCBsaWZlX3RhYmxlX3BjYV9ORikNCnJvd25hbWVzKGxpZmVfYmlzKT0gbGlmZV9iaXNbLDFdDQoNCmxpZmVfdGFibGVfcGNhX05GIDwtbG9nKGxpZmVfYmlzWywtYygxLDIsMyw0KV0pDQpyZXNfTkYuYWNwPC1wcmNvbXAobGlmZV90YWJsZV9wY2FfTkYsc2NhbGU9VCxjZW50ZXIgPSBUKQ0KDQoNCmNvdW50cnkgPC0gIk5ldGhlcmxhbmRzIg0KZ2VuZGVyIDwtICJNYWxlIg0KeWVhciA8LSBzZXEoMTk0OCwyMDEwLDEpDQoNCmxpZmVfdGFibGVfcGNhX1VTQU0gPC0gbGlmZV90YWJsZV9waXZvdCAlPiUgDQogIGZpbHRlcihsaWZlX3RhYmxlX3Bpdm90JENvdW50cnk9PWNvdW50cnksIGxpZmVfdGFibGVfcGl2b3QkR2VuZGVyPT1nZW5kZXIgLGxpZmVfdGFibGVfcGl2b3QkWWVhciAlaW4lIHllYXIpIA0KDQpsaWZlX3llYXIgPSBsaWZlX3RhYmxlX3BjYV9VU0FNICU+JSAgc2VsZWN0KFllYXIpDQpsaWZlX2JpcyA9IGNiaW5kKGxpZmVfeWVhciwgbGlmZV90YWJsZV9wY2FfVVNBTSkNCnJvd25hbWVzKGxpZmVfYmlzKT0gbGlmZV9iaXNbLDFdDQoNCmxpZmVfdGFibGVfcGNhX1VTQU0gPC1sb2cobGlmZV9iaXNbLC1jKDEsMiwzLDQpXSkNCnJlc19VU0FNLmFjcDwtcHJjb21wKGxpZmVfdGFibGVfcGNhX1VTQU0sc2NhbGU9VCxjZW50ZXIgPSBUKQ0KDQpgYGANCg0KLSBbIF0gQ29tYmluZXogbGVzIGBzY3JlZXBsb3RzYCBwb3VyIGRpZmbDqXJlbnRzIHBheXMgKHBvdXIgY2hhcXVlIHNleGUpLiBDb21tZW50YWlyZQ0KDQoNCg0KIyBNb2TDqGxlIExlZS1DYXJ0ZXIgcG91ciBsYSBtb3J0YWxpdMOpIGF1eCDDiXRhdHMtVW5pcw0KDQpBdSBjb3VycyBkdSBzacOoY2xlIGRlcm5pZXIsIGF1eCDDiXRhdHMtVW5pcyBldCBlbiBFdXJvcGUgb2NjaWRlbnRhbGUsDQpsZXMgcXVvdGllbnRzIGRlIG1vcnRhbGl0w6kgw6AgdG91cyBsZXMgw6JnZXMgb250IHByw6lzZW50w6kgdW5lIHRlbmRhbmNlIGfDqW7DqXJhbGUgw6AgbGEgYmFpc3NlLg0KQ2V0dGUgdGVuZGFuY2Ugw6AgbGEgYmFpc3NlIG4nYSBwYXMgdG91am91cnMgw6l0w6kgaG9tb2fDqG5lIGVudHJlIGxlcyDDomdlcy4NCg0KTGUgbW9kw6hsZSBkZSBMZWUtQ2FydGVyIGEgw6l0w6kgY29uw6d1IHBvdXIgbW9kw6lsaXNlciBldCBwcsOpdm9pciBsJ8Opdm9sdXRpb24gZHUgcXVvdGllbnQgbG9nLW1vcnRhbGl0w6kuDQpsJ8Opdm9sdXRpb24gZGVzIHF1b3RpZW50cyBkZSBtb3J0YWxpdMOpIGxvZ2FyaXRobWlxdWUgcG91ciBsZXMgw4l0YXRzLVVuaXMgYXUgY291cnMgZHUgWFhlIHNpw6hjbGUuDQoNClNvaXQgJEFfe3gsdH0kIGxlIGxvZ2FyaXRobWUgZHUgcXVvdGllbnQgZGUgbW9ydGFsaXTDqSDDoCBsJ8OiZ2UgJHgkIHBlbmRhbnQgbCdhbm7DqWUgJHRcaW4gVCQuDQpwb3VyIHVuZSBwb3B1bGF0aW9uIGRvbm7DqWUgKGTDqWZpbmllIHBhciBsZSBzZXhlIGV0IGxlIHBheXMpLg0KDQpMZSBtb2TDqGxlIGRlIExlZS1DYXJ0ZXIgc3VwcG9zZSBxdWUgbGVzIHF1b3RpZW50cyBkZSBtb3J0YWxpdMOpIGxvZ2FyaXRobWlxdWVzIG9ic2VydsOpcw0Kc29udCDDqWNoYW50aWxsb25uw6lzIHNlbG9uIGxlIG1vZMOobGUgc3VpdmFudA0KXFsNCkFfe3gsdH0gXHNpbV97XHRleHR7aW5kw6lwZW5kYW50fX0gYV94ICsgYl94IFxrYXBwYV90ICsgXGVwc2lsb25fe3gsdH0NClxdDQpvw7kgJChhX3gpX3gsIChiX3gpX3gkIGV0ICQoXGthcHBhX3QpX3QkIHNvbnQgZGVzIHZlY3RldXJzIGluY29ubnVzIHF1aSBzYXRpc2ZvbnQNClxbDQphX3ggPSBcZnJhY3sxfXt8VHx9XHN1bV97dCBcaW4gVH0gQV97eCx0fVxxcXVhZCBcc3VtX3t0XGluIFR9IFxrYXBwYV90ID0gMCBccXF1YWQgXHN1bV97eH0gYl94XjIgPTENClxdDQpldCAkXGVwc2lsb25fe3gsdH0kIHNvbnQgZGVzIHZhcmlhYmxlcyBhbMOpYXRvaXJlcyBpLmkuZC4gZ2F1c3NpZW5uZXMuDQoNCg0KIyMgRG9ubsOpZXMgVVMNCg0KDQotIFsgXSBBanVzdGV6IHVuIG1vZMOobGUgTGVlLUNhcnRlciBzdXIgbGVzIGRvbm7DqWVzIGFtw6lyaWNhaW5lcyAocG91ciBsZXMgZG9ubsOpZXMgbWFzY3VsaW5lcyBldCBmw6ltaW5pbmVzKSBlbiB2b3VzIGVudHJhw65uYW50IHN1ciBsZXMgYW5uw6llcyBgMTkzM2AganVzcXUnw6AgYDE5OTVgLg0KLSBbIF0gQ29tcGFyZXogbCdhanVzdGVtZW50IGZvdXJuaSBwYXIgbGUgbW9kw6hsZSBkZSBMZWUtQ2FydGVyIGF2ZWMgbCdhanVzdGVtZW50IGZvdXJuaSBwYXIgdW4gbW9kw6hsZSBTVkQgdHJvbnF1w6kgZGUgcmFuZyAkMiQuDQotIFsgXSBDb21wYXJleiBsZXMgdmVjdGV1cnMgYXZlYyAkKGFfeClfeCwgKGJfeClfeCQgZXQgJChca2FwcGFfdClfdCQgYXZlYyBsZXMgdmVjdGV1cnMgc2luZ3VsaWVycyBhcHByb3ByacOpcy4NCi0gWyBdIFV0aWxpc2V6IGxlIG1vZMOobGUgZGUgTGVlLUNhcnRlciBwb3VyIHByw6lkaXJlIGxlcyBxdW90aWVudHMgZGUgbW9ydGFsaXTDqSBwb3VyIGxlcyBhbm7DqWVzIDIwMDAkIMOgIDIwMTUkLg0KDQpgYGB7cn0NCmEzM185NSA9IHNlcSgxOTMzLDE5OTUsMSkNCg0KbGlmZV9jYXJ0IDwtIGxpZmVfdGFibGUNCmxpZmVfY2FydCA8LSBzZWxlY3QobGlmZV9jYXJ0LEFnZSxDb3VudHJ5LEdlbmRlcixZZWFyLHF4KSAlPiUNCiAgZmlsdGVyKGxpZmVfY2FydCRZZWFyICVpbiUgYTMzXzk1LCBsaWZlX2NhcnQkQ291bnRyeSA9PSAiVVNBIikNCg0KDQpsaWZlX2NhcnRfbSA8LSBsaWZlX2NhcnQgJT4lIA0KICBmaWx0ZXIobGlmZV9jYXJ0JEdlbmRlciA9PSAiTWFsZSIpDQpsaWZlX2NhcnRfZiA8LSBsaWZlX2NhcnQgJT4lIA0KICBmaWx0ZXIobGlmZV9jYXJ0JEdlbmRlciA9PSAiRmVtYWxlIikNCg0KbGlmZV9jYXJ0X21bLGMoIkdlbmRlciIsIkNvdW50cnkiKV0gPC0gbGlzdChOVUxMKQ0KbGlmZV9jYXJ0X21bLDNdIDwtIGxvZyhsaWZlX2NhcnRfbVssM10pDQpsaWZlX2NhcnRfbSA8LSBsaWZlX2NhcnRfbSAlPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IFllYXIsdmFsdWVzX2Zyb20gPSBxeCkNCg0KDQpsaWZlX2NhcnRfZlssYygiR2VuZGVyIiwiQ291bnRyeSIpXSA8LSBsaXN0KE5VTEwpDQpsaWZlX2NhcnRfZlssM10gPC0gbG9nKGxpZmVfY2FydF9mWywzXSkNCmxpZmVfY2FydF9mIDwtIGxpZmVfY2FydF9mICU+JQ0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gWWVhcix2YWx1ZXNfZnJvbSA9IHF4KQ0KDQojbGlmZV9jYXJ0X20NCg0KYW0gPSB2ZWN0b3IoIm51bWVyaWMiLDExMCkNCmZvcihpIGluIDE6MTEwKXsNCiAgYW1baV0gPSAoMS82MykgKiBzdW0obGlmZV9jYXJ0X21baSwyOjY0XSkNCn0NCkEgPC0gbGlmZV9jYXJ0X21bLTFdIC0gYW0NCkEgPC0gdChBKQ0KY29sbmFtZXMoQSkgPSBzZXEoMToxMTApLTENCmRlYyA8LSBzdmQoQSkNCnNpbmdtIDwtIHNxcnQoZGVjJGRbMV0pDQpibSA8LSBkZWMkdlssMV0NCmttIDwtIC1kZWMkdVssMV0qc2luZ20NCg0KYWYgPSB2ZWN0b3IoIm51bWVyaWMiLDExMCkNCmZvcihpIGluIDE6MTEwKXsNCiAgYWZbaV0gPSAoMS82MykgKiBzdW0obGlmZV9jYXJ0X2ZbaSwyOjY0XSkNCn0NCkIgPC0gbGlmZV9jYXJ0X2ZbLTFdIC0gYWYNCkIgPC0gdChCKQ0KY29sbmFtZXMoQikgPSBzZXEoMToxMTApLTENCmRlYyA8LSBzdmQoQikNCnNpbmdmIDwtIHNxcnQoZGVjJGRbMV0pDQpiZiA8LSBkZWMkdlssMV0NCmtmIDwtIC1kZWMkdVssMV0qc2luZ2YNCg0KdHJlbmQxIDwtIGRhdGEuZnJhbWUoWWVhciA9IDE5MzM6MTk5NSxrYXBwYSA9IGttLEdlbmRlciA9ICJNYWxlIixjb3VyYmUgPSAiMTkzMy0xOTk1IikNCnRyZW5kMiA8LSBkYXRhLmZyYW1lKFllYXIgPSAxOTMzOjE5OTUsa2FwcGEgPSBrZixHZW5kZXIgPSAiRmVtYWxlIixjb3VyYmUgPSIxOTMzLTE5OTUiKQ0KdHJlbmQzIDwtIGRhdGEuZnJhbWUoWWVhciA9IDE5OTY6MjAxNSxrYXBwYSA9IDAsR2VuZGVyID0iTWFsZSIsY291cmJlID0gIjE5OTYtMjAxNSIpDQp0cmVuZDQgPC0gZGF0YS5mcmFtZShZZWFyID0gMTk5NjoyMDE1LGthcHBhID0gMCxHZW5kZXIgPSJGZW1hbGUiLGNvdXJiZSA9ICIxOTk2LTIwMTUiKQ0KDQpBMjIgPC0gbGlmZV9jYXJ0ICU+JQ0KICBmaWx0ZXIobGlmZV9jYXJ0JEdlbmRlciA9PSAiTWFsZSIpICU+JQ0KICBzZWxlY3QoLWMoR2VuZGVyLENvdW50cnkpKSAlPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IEFnZSx2YWx1ZXNfZnJvbSA9IHF4KSAlPiUNCiAgc2VsZWN0KC1ZZWFyKSANCkEyMiA8LSBsb2coQTIyKQ0KDQpkZWMyMiA8LSBzdmQoQTIyLDIsMikNCg0KDQojbG0odHJlbmQxJGthcHBhfnRyZW5kMSRZZWFyKQ0KZm9yKGkgaW4gMTpucm93KHRyZW5kMykpew0KICB0cmVuZDNbaSwyXSA9IHRyZW5kM1tpLDFdKi0wLjAzMTY0KzYyLjEzMjIwDQp9DQoNCg0KI2xtKHRyZW5kMiRrYXBwYX50cmVuZDIkWWVhcikNCmZvcihpIGluIDE6bnJvdyh0cmVuZDQpKXsNCiAgdHJlbmQ0W2ksMl0gPSB0cmVuZDRbaSwxXSotMC4wMzc0NSs3My41NDgxMA0KfQ0KDQp0cmVuZCA8LSByYmluZCh0cmVuZDEsdHJlbmQyLHRyZW5kMyx0cmVuZDQpDQoNCihnZ3Bsb3QodHJlbmQsYWVzKFllYXIsa2FwcGEpKSANCiAgKyBnZW9tX2xpbmUoYWVzKGNvbG9yID0gY291cmJlLCBncm91cD1HZW5kZXIpKSANCiAgKyBnZ3RpdGxlKCJDb2VmZmljaWVudCBkZSBtb3J0YWxpdMOpIHBvdXIgbGVzIGFubsOpZXMgMTkzMyDDoCAxOTk1IGV0IFxuIHByw6lkaWN0aW9uIGRlIDE5OTYgw6AgMjAxNSIpIA0KICArIGZhY2V0X2dyaWQoR2VuZGVyfi4pIA0KICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZC5pdGFsaWMiKSkNCiAgKyB0aGVtZV9idygpKSAgJT4lDQogIHBsb3RseTo6Z2dwbG90bHkoaGVpZ2h0ID00NTAsIHdpZHRoPTgwMCkNCg0KYGBgDQoNCi0gWyBdIFRyYWNleiBsZXMgcHLDqWRpY3Rpb25zIGV0IGxlcyBvYnNlcnZhdGlvbnMgcG91ciBsZXMgYW5uw6llcyAyMDAwLCAyMDA1LCAyMDEwIGV0IDIwMTUuDQoNCmBgYHtyfQ0KYTk2XzE1ID0gc2VxKDE5OTYsMjAxNSwxKQ0KDQpsaWZlX2NhcnQyIDwtIGxpZmVfdGFibGUNCmxpZmVfY2FydDIgPC0gc2VsZWN0KGxpZmVfY2FydDIsQWdlLENvdW50cnksR2VuZGVyLFllYXIscXgpICU+JQ0KICBmaWx0ZXIobGlmZV9jYXJ0MiRZZWFyICVpbiUgYTk2XzE1LCBsaWZlX2NhcnQyJENvdW50cnkgPT0gIlVTQSIpDQoNCg0KbGlmZV9jYXJ0X20yIDwtIGxpZmVfY2FydDIgJT4lIA0KICBmaWx0ZXIobGlmZV9jYXJ0MiRHZW5kZXIgPT0gIk1hbGUiKQ0KbGlmZV9jYXJ0X2YyIDwtIGxpZmVfY2FydDIgJT4lIA0KICBmaWx0ZXIobGlmZV9jYXJ0MiRHZW5kZXIgPT0gIkZlbWFsZSIpDQoNCmxpZmVfY2FydF9tMlssYygiR2VuZGVyIiwiQ291bnRyeSIpXSA8LSBsaXN0KE5VTEwpDQpsaWZlX2NhcnRfbTJbLDNdIDwtIGxvZyhsaWZlX2NhcnRfbTJbLDNdKQ0KbGlmZV9jYXJ0X20yIDwtIGxpZmVfY2FydF9tMiAlPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IFllYXIsdmFsdWVzX2Zyb20gPSBxeCkNCg0KDQpsaWZlX2NhcnRfZjJbLGMoIkdlbmRlciIsIkNvdW50cnkiKV0gPC0gbGlzdChOVUxMKQ0KbGlmZV9jYXJ0X2YyWywzXSA8LSBsb2cobGlmZV9jYXJ0X2YyWywzXSkNCmxpZmVfY2FydF9mMiA8LSBsaWZlX2NhcnRfZjIgJT4lDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBZZWFyLHZhbHVlc19mcm9tID0gcXgpDQoNCiNsaWZlX2NhcnRfbQ0KDQphbTIgPSB2ZWN0b3IoIm51bWVyaWMiLDExMCkNCmZvcihpIGluIDE6MTEwKXsNCiAgYW0yW2ldID0gKDEvMjApICogc3VtKGxpZmVfY2FydF9tMltpLDI6MjFdKQ0KfQ0KQTIgPC0gbGlmZV9jYXJ0X20yWy0xXSAtIGFtMg0KQTIgPC0gdChBMikNCmNvbG5hbWVzKEEyKSA9IHNlcSgxOjExMCktMQ0KZGVjMiA8LSBzdmQoQTIpDQpzaW5nbSA8LSBzcXJ0KGRlYzIkZFsxXSkNCmJtMiA8LSBkZWMyJHZbLDFdDQprbTIgPC0gLWRlYzIkdVssMV0qc2luZ20NCg0KYWYyID0gdmVjdG9yKCJudW1lcmljIiwxMTApDQpmb3IoaSBpbiAxOjExMCl7DQogIGFmMltpXSA9ICgxLzIwKSAqIHN1bShsaWZlX2NhcnRfZjJbaSwyOjIxXSkNCn0NCkIyIDwtIGxpZmVfY2FydF9mMlstMV0gLSBhZjINCkIyIDwtIHQoQjIpDQpjb2xuYW1lcyhCMikgPSBzZXEoMToxMTApLTENCmRlYzIgPC0gc3ZkKEIyKQ0Kc2luZ2YgPC0gc3FydChkZWMyJGRbMV0pDQpiZjIgPC0gZGVjMiR2WywxXQ0Ka2YyIDwtIC1kZWMyJHVbLDFdKnNpbmdmDQoNCnRyZW5kM1ssNF0gPSAiUHLDqWRpY3Rpb24iDQp0cmVuZDRbLDRdID0gIlByw6lkaWN0aW9uIg0KdHJlbmQ1IDwtIGRhdGEuZnJhbWUoWWVhciA9IDE5OTY6MjAxNSxrYXBwYSA9IGttMixHZW5kZXIgPSAiTWFsZSIsY291cmJlID0gIk9ic2VydmF0aW9uIikNCnRyZW5kNiA8LSBkYXRhLmZyYW1lKFllYXIgPSAxOTk2OjIwMTUsa2FwcGEgPSBrZjIsR2VuZGVyID0gIkZlbWFsZSIsY291cmJlID0gIk9ic2VydmF0aW9uIikNCg0KDQojcXVvdGllbnRzIGRlIG1vcnRhbGl0w6kgcHLDqWRpdHMNCg0KdHR0bSA8LSBleHAodChhbTIgKyBibTIlKiV0KHRyZW5kMyRrYXBwYSkpKQ0KdHR0ZiA8LWV4cCh0KGFmMiArIGJmMiUqJXQodHJlbmQ0JGthcHBhKSkpDQoNCmxpZmVfY2FydHggPC0gc2VsZWN0KGxpZmVfY2FydDIsWWVhcixBZ2UsQ291bnRyeSxHZW5kZXIscXgpICU+JQ0KICBmaWx0ZXIobGlmZV9jYXJ0MiRZZWFyICVpbiUgYTk2XzE1LCBsaWZlX2NhcnQyJENvdW50cnkgPT0gIlVTQSIpICU+JQ0KICBzZWxlY3QoLWMoQ291bnRyeSkpDQogIA0KICANCmxpZmVfY2FydHg8LWRhdGEuZnJhbWUobGlmZV9jYXJ0eCx0eXBlPSJPYnNlcnZhdGlvbnMiKQ0KDQoNCnllYXJ0dHQgPC0gZGF0YS5mcmFtZShZZWFyID0gMTk5NjoyMDE1KQ0KdHR0bSA8LSBjYmluZCh5ZWFydHR0LHR0dG0pDQp0dHRtIDwtIHBpdm90X2xvbmdlcih0dHRtLGNvbHMgPSAtYyhZZWFyKSxuYW1lc190byA9ICJBZ2UiLHZhbHVlc190byA9ICJxeCIpDQp0dHRtPC0gZGF0YS5mcmFtZSh0dHRtLHR5cGU9IlByw6lkaWN0aW9ucyIsIEdlbmRlciA9ICJNYWxlIikNCg0KdHR0ZiA8LSBjYmluZCh5ZWFydHR0LHR0dGYpDQp0dHRmIDwtIHBpdm90X2xvbmdlcih0dHRmLGNvbHMgPSAtYyhZZWFyKSxuYW1lc190byA9ICJBZ2UiLHZhbHVlc190byA9ICJxeCIpDQp0dHRmPC0gZGF0YS5mcmFtZSh0dHRmLHR5cGU9IlByw6lkaWN0aW9ucyIsIEdlbmRlciA9ICJGZW1hbGUiKQ0KDQoNCnR0dCA8LSByYmluZCh0dHRtLHR0dGYsbGlmZV9jYXJ0eCkNCg0KDQoNCnR0dCA8LSB0dHQlPiUNCiAgZmlsdGVyKHR0dCRZZWFyJWluJSBjKDIwMDAsMjAwNSwyMDEwLDIwMTUpKQ0KDQp0dHRbLDJdIDwtIGFzLm51bWVyaWModHR0WywyXSkNCg0KKGdncGxvdCh0dHQsIGFlcyhBZ2UscXgsIGZyYW1lPVllYXIsIGdyb3VwPUdlbmRlcikpDQorZ2VvbV9saW5lKGFlcyhjb2xvcj10eXBlKSkNCiAgK2xhYnModGl0bGU9J0NvbXBhcmFpc29uIGRlcyBxdW90aWVudHMgZGUgbW9ydGFsaXTDqSBwcsOpZGl0cyBldCBvYnNlcnbDqXMnLCB5PSdRdW90aWVudCBkZSBtb3J0YWxpdMOpJywgeD0nYWdlJykNCiAgKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQuaXRhbGljIikpDQogICsgZmFjZXRfZ3JpZCh+R2VuZGVyKStzY2FsZV95X2xvZzEwKGxhYmVscz1zY2llbnRpZmljKQ0KICArIHRoZW1lX2J3KCkpJT4lDQogIHBsb3RseTo6Z2dwbG90bHkoaGVpZ2h0ID0gNTAwLCB3aWR0aD03NTApDQoNCmBgYA0KDQojIyBBcHBsaWNhdGlvbiBkdSBtb2TDqGxlIGRlIExlZS1DYXJ0ZXIgw6AgdW4gcGF5cyBldXJvcMOpZW4NCg0KLSBbIF0gQWp1c3RleiB1biBtb2TDqGxlIGRlIExlZS1DYXJ0ZXIgw6AgdW4gcGF5cyBldXJvcMOpZW4uDQotIFsgXSBDb21tZW50YWlyZQ0KLSBbIF0gQ29tcGFyZXogYXZlYyBsYSBTVkQgdHJvbnF1w6llIGRlIHJhbmcgMi4NCi0gWyBdIFV0aWxpc2VyIGxlIG1vZMOobGUgZGUgTGVlLUNhcnRlciBwb3VyIHByw6lkaXJlIGxlcyBxdW90aWVudHMgZGUgbW9ydGFsaXTDqSBwb3VyIGxlcyBhbm7DqWVzICQyMDAwJCDDoCAkMjAxNSQuDQoNCg0KYGBge3J9DQojTGVlIGNhcnRlciBldXJvcGUNCmEzM185NSA9IHNlcSgxOTMzLDE5OTUsMSkNCg0KbGlmZV9jYXJ0IDwtIGxpZmVfdGFibGUNCmxpZmVfY2FydCA8LSBzZWxlY3QobGlmZV9jYXJ0LEFnZSxDb3VudHJ5LEdlbmRlcixZZWFyLHF4KSAlPiUNCiAgZmlsdGVyKGxpZmVfY2FydCRZZWFyICVpbiUgYTMzXzk1LCBsaWZlX2NhcnQkQ291bnRyeSA9PSAiRnJhbmNlIikNCg0KDQpsaWZlX2NhcnRfbSA8LSBsaWZlX2NhcnQgJT4lIA0KICBmaWx0ZXIobGlmZV9jYXJ0JEdlbmRlciA9PSAiTWFsZSIpDQpsaWZlX2NhcnRfZiA8LSBsaWZlX2NhcnQgJT4lIA0KICBmaWx0ZXIobGlmZV9jYXJ0JEdlbmRlciA9PSAiRmVtYWxlIikNCg0KbGlmZV9jYXJ0X21bLGMoIkdlbmRlciIsIkNvdW50cnkiKV0gPC0gbGlzdChOVUxMKQ0KbGlmZV9jYXJ0X21bLDNdIDwtIGxvZyhsaWZlX2NhcnRfbVssM10pDQpsaWZlX2NhcnRfbSA8LSBsaWZlX2NhcnRfbSAlPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IFllYXIsdmFsdWVzX2Zyb20gPSBxeCkNCg0KDQpsaWZlX2NhcnRfZlssYygiR2VuZGVyIiwiQ291bnRyeSIpXSA8LSBsaXN0KE5VTEwpDQpsaWZlX2NhcnRfZlssM10gPC0gbG9nKGxpZmVfY2FydF9mWywzXSkNCmxpZmVfY2FydF9mIDwtIGxpZmVfY2FydF9mICU+JQ0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gWWVhcix2YWx1ZXNfZnJvbSA9IHF4KQ0KDQojbGlmZV9jYXJ0X20NCg0KYW0gPSB2ZWN0b3IoIm51bWVyaWMiLDExMCkNCmZvcihpIGluIDE6MTEwKXsNCiAgYW1baV0gPSAoMS82MykgKiBzdW0obGlmZV9jYXJ0X21baSwyOjY0XSkNCn0NCkEgPC0gbGlmZV9jYXJ0X21bLTFdIC0gYW0NCkEgPC0gdChBKQ0KY29sbmFtZXMoQSkgPSBzZXEoMToxMTApLTENCmRlYyA8LSBzdmQoQSkNCnNpbmdtIDwtIHNxcnQoZGVjJGRbMV0pDQpibSA8LSBkZWMkdlssMV0NCmttIDwtIC1kZWMkdVssMV0qc2luZ20NCg0KYWYgPSB2ZWN0b3IoIm51bWVyaWMiLDExMCkNCmZvcihpIGluIDE6MTEwKXsNCiAgYWZbaV0gPSAoMS82MykgKiBzdW0obGlmZV9jYXJ0X2ZbaSwyOjY0XSkNCn0NCkIgPC0gbGlmZV9jYXJ0X2ZbLTFdIC0gYWYNCkIgPC0gdChCKQ0KY29sbmFtZXMoQikgPSBzZXEoMToxMTApLTENCmRlYyA8LSBzdmQoQikNCnNpbmdmIDwtIHNxcnQoZGVjJGRbMV0pDQpiZiA8LSBkZWMkdlssMV0NCmtmIDwtIC1kZWMkdVssMV0qc2luZ2YNCg0KdHJlbmQxIDwtIGRhdGEuZnJhbWUoWWVhciA9IDE5MzM6MTk5NSxrYXBwYSA9IGttLEdlbmRlciA9ICJNYWxlIixjb3VyYmUgPSAiMTkzMy0xOTk1IikNCnRyZW5kMiA8LSBkYXRhLmZyYW1lKFllYXIgPSAxOTMzOjE5OTUsa2FwcGEgPSBrZixHZW5kZXIgPSAiRmVtYWxlIixjb3VyYmUgPSIxOTMzLTE5OTUiKQ0KdHJlbmQzIDwtIGRhdGEuZnJhbWUoWWVhciA9IDE5OTY6MjAxNSxrYXBwYSA9IDAsR2VuZGVyID0iTWFsZSIsY291cmJlID0gIjE5OTYtMjAxNSIpDQp0cmVuZDQgPC0gZGF0YS5mcmFtZShZZWFyID0gMTk5NjoyMDE1LGthcHBhID0gMCxHZW5kZXIgPSJGZW1hbGUiLGNvdXJiZSA9ICIxOTk2LTIwMTUiKQ0KDQpBMjIgPC0gbGlmZV9jYXJ0ICU+JQ0KICBmaWx0ZXIobGlmZV9jYXJ0JEdlbmRlciA9PSAiTWFsZSIpICU+JQ0KICBzZWxlY3QoLWMoR2VuZGVyLENvdW50cnkpKSAlPiUNCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9IEFnZSx2YWx1ZXNfZnJvbSA9IHF4KSAlPiUNCiAgc2VsZWN0KC1ZZWFyKSANCkEyMiA8LSBsb2coQTIyKQ0KDQpkZWMyMiA8LSBzdmQoQTIyLDIsMikNCg0KDQojbG0odHJlbmQxJGthcHBhfnRyZW5kMSRZZWFyKQ0KZm9yKGkgaW4gMTpucm93KHRyZW5kMykpew0KICB0cmVuZDNbaSwyXSA9IHRyZW5kM1tpLDFdKi0wLjAzMTY0KzYyLjEzMjIwDQp9DQoNCg0KI2xtKHRyZW5kMiRrYXBwYX50cmVuZDIkWWVhcikNCmZvcihpIGluIDE6bnJvdyh0cmVuZDQpKXsNCiAgdHJlbmQ0W2ksMl0gPSB0cmVuZDRbaSwxXSotMC4wMzc0NSs3My41NDgxMA0KfQ0KDQp0cmVuZCA8LSByYmluZCh0cmVuZDEsdHJlbmQyLHRyZW5kMyx0cmVuZDQpDQoNCg0KKGdncGxvdCh0cmVuZCxhZXMoWWVhcixrYXBwYSkpIA0KICArIGdlb21fbGluZShhZXMoY29sb3IgPSBjb3VyYmUsIGdyb3VwPUdlbmRlcikpIA0KICArIGdndGl0bGUoIkNvZWZmaWNpZW50IGRlIG1vcnRhbGl0w6kgcG91ciBsZXMgYW5uw6llcyAxOTMzIMOgIDE5OTUgZXQgXG4gcHLDqWRpY3Rpb24gZGUgMTk5NSDDoCAyMDE1IikgDQogICsgZmFjZXRfZ3JpZChHZW5kZXJ+LikgDQogICsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlPSJib2xkLml0YWxpYyIpKQ0KICArIHRoZW1lX2J3KCkpICAlPiUNCiAgcGxvdGx5OjpnZ3Bsb3RseShoZWlnaHQgPTQ1MCwgd2lkdGg9ODAwKQ0KDQpgYGANCg0KLSBbIF0gQ29tbWVudGFpcmUNCg0KTGUgY29lZmZpY2llbnQgZGUgbW9ydGFsaXTDqSBkZSBsYSBmcmFuY2Ugc2VtYmxlIGVuIG1veWVubmUgYWxpZ27DqSBhdmVjIGxlIGNvZWZmaWNpZW50IGRlIG1vcnRhbGl0w6kgb2J0ZW51IHBhciBsZSByZWdyw6lzc2VtZW50IGxpbsOpYWlyZS4gRW4gZWZmZXQsIGNlIGRlcm5pZXIgZXN0IHVuIHByb2xvbmdlbWVudCBkdSBjb2VmZmljaWVudCBkZSBtb3J0YWxpdMOpIDE5MzMgw6AgMTk5NS4NCg0KDQogICBUcmFjZXogbGVzIHByw6lkaWN0aW9ucyBldCBsZXMgb2JzZXJ2YXRpb25zIHBvdXIgbGVzIGFubsOpZXMgJDIwMDAsIDIwMDUsIDIwMTAsIDIwMTUkLg0KDQpgYGB7cn0NCmE5Nl8xNSA9IHNlcSgxOTk2LDIwMTUsMSkNCg0KbGlmZV9jYXJ0MiA8LSBsaWZlX3RhYmxlDQpsaWZlX2NhcnQyIDwtIHNlbGVjdChsaWZlX2NhcnQyLEFnZSxDb3VudHJ5LEdlbmRlcixZZWFyLHF4KSAlPiUNCiAgZmlsdGVyKGxpZmVfY2FydDIkWWVhciAlaW4lIGE5Nl8xNSwgbGlmZV9jYXJ0MiRDb3VudHJ5ID09ICJGcmFuY2UiKQ0KDQoNCmxpZmVfY2FydF9tMiA8LSBsaWZlX2NhcnQyICU+JSANCiAgZmlsdGVyKGxpZmVfY2FydDIkR2VuZGVyID09ICJNYWxlIikNCmxpZmVfY2FydF9mMiA8LSBsaWZlX2NhcnQyICU+JSANCiAgZmlsdGVyKGxpZmVfY2FydDIkR2VuZGVyID09ICJGZW1hbGUiKQ0KDQpsaWZlX2NhcnRfbTJbLGMoIkdlbmRlciIsIkNvdW50cnkiKV0gPC0gbGlzdChOVUxMKQ0KbGlmZV9jYXJ0X20yWywzXSA8LSBsb2cobGlmZV9jYXJ0X20yWywzXSkNCmxpZmVfY2FydF9tMiA8LSBsaWZlX2NhcnRfbTIgJT4lDQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBZZWFyLHZhbHVlc19mcm9tID0gcXgpDQoNCg0KbGlmZV9jYXJ0X2YyWyxjKCJHZW5kZXIiLCJDb3VudHJ5IildIDwtIGxpc3QoTlVMTCkNCmxpZmVfY2FydF9mMlssM10gPC0gbG9nKGxpZmVfY2FydF9mMlssM10pDQpsaWZlX2NhcnRfZjIgPC0gbGlmZV9jYXJ0X2YyICU+JQ0KICBwaXZvdF93aWRlcihuYW1lc19mcm9tID0gWWVhcix2YWx1ZXNfZnJvbSA9IHF4KQ0KDQojbGlmZV9jYXJ0X20NCg0KYW0yID0gdmVjdG9yKCJudW1lcmljIiwxMTApDQpmb3IoaSBpbiAxOjExMCl7DQogIGFtMltpXSA9ICgxLzIwKSAqIHN1bShsaWZlX2NhcnRfbTJbaSwyOjIxXSkNCn0NCkEyIDwtIGxpZmVfY2FydF9tMlstMV0gLSBhbTINCkEyIDwtIHQoQTIpDQpjb2xuYW1lcyhBMikgPSBzZXEoMToxMTApLTENCmRlYzIgPC0gc3ZkKEEyKQ0Kc2luZ20gPC0gc3FydChkZWMyJGRbMV0pDQpibTIgPC0gZGVjMiR2WywxXQ0Ka20yIDwtIC1kZWMyJHVbLDFdKnNpbmdtDQoNCg0KYWYyID0gdmVjdG9yKCJudW1lcmljIiwxMTApDQpmb3IoaSBpbiAxOjExMCl7DQogIGFmMltpXSA9ICgxLzIwKSAqIHN1bShsaWZlX2NhcnRfZjJbaSwyOjIxXSkNCn0NCkIyIDwtIGxpZmVfY2FydF9mMlstMV0gLSBhZjINCkIyIDwtIHQoQjIpDQpjb2xuYW1lcyhCMikgPSBzZXEoMToxMTApLTENCmRlYzIgPC0gc3ZkKEIyKQ0Kc2luZ2YgPC0gc3FydChkZWMyJGRbMV0pDQpiZjIgPC0gZGVjMiR2WywxXQ0Ka2YyIDwtIC1kZWMyJHVbLDFdKnNpbmdmDQoNCnRyZW5kM1ssNF0gPSAiUHLDqWRpY3Rpb24iDQp0cmVuZDRbLDRdID0gIlByw6lkaWN0aW9uIg0KdHJlbmQ1IDwtIGRhdGEuZnJhbWUoWWVhciA9IDE5OTY6MjAxNSxrYXBwYSA9IGttMixHZW5kZXIgPSAiTWFsZSIsY291cmJlID0gIk9ic2VydmF0aW9uIikNCnRyZW5kNiA8LSBkYXRhLmZyYW1lKFllYXIgPSAxOTk2OjIwMTUsa2FwcGEgPSBrZjIsR2VuZGVyID0gIkZlbWFsZSIsY291cmJlID0gIk9ic2VydmF0aW9uIikNCg0KDQojcXVvdGllbnRzIGRlIG1vcnRhbGl0w6kgcHLDqWRpdHMNCg0KdHR0bSA8LSBleHAodChhbSArIGJtICUqJSB0KHRyZW5kMyRrYXBwYSkpKQ0KdHR0ZiA8LSBleHAodChhZiArIGJmICUqJSB0KHRyZW5kNCRrYXBwYSkpKQ0KDQoNCmxpZmVfY2FydHggPC0gc2VsZWN0KGxpZmVfY2FydDIsWWVhcixBZ2UsQ291bnRyeSxHZW5kZXIscXgpICU+JQ0KICBmaWx0ZXIobGlmZV9jYXJ0MiRZZWFyICVpbiUgYTk2XzE1LCBsaWZlX2NhcnQyJENvdW50cnkgPT0gIkZyYW5jZSIpICU+JQ0KICBzZWxlY3QoLWMoQ291bnRyeSkpDQogIA0KICANCmxpZmVfY2FydHg8LWRhdGEuZnJhbWUobGlmZV9jYXJ0eCx0eXBlPSJvYnMiKQ0KDQoNCnllYXJ0dHQgPC0gZGF0YS5mcmFtZShZZWFyID0gMTk5NjoyMDE1KQ0KdHR0bSA8LSBjYmluZCh5ZWFydHR0LHR0dG0pDQp0dHRtIDwtIHBpdm90X2xvbmdlcih0dHRtLGNvbHMgPSAtYyhZZWFyKSxuYW1lc190byA9ICJBZ2UiLHZhbHVlc190byA9ICJxeCIpDQp0dHRtPC0gZGF0YS5mcmFtZSh0dHRtLHR5cGU9InByZWRpIiwgR2VuZGVyID0gIk1hbGUiKQ0KDQp0dHRmIDwtIGNiaW5kKHllYXJ0dHQsdHR0ZikNCnR0dGYgPC0gcGl2b3RfbG9uZ2VyKHR0dGYsY29scyA9IC1jKFllYXIpLG5hbWVzX3RvID0gIkFnZSIsdmFsdWVzX3RvID0gInF4IikNCnR0dGY8LSBkYXRhLmZyYW1lKHR0dGYsdHlwZT0icHJlZGkiLCBHZW5kZXIgPSAiRmVtYWxlIikNCg0KDQp0dHQgPC0gcmJpbmQodHR0bSx0dHRmLGxpZmVfY2FydHgpDQoNCg0KDQp0dHQgPC0gdHR0JT4lDQogIGZpbHRlcih0dHQkWWVhciVpbiUgYygyMDAwLDIwMDUsMjAxMCwyMDE1KSkNCg0KdHR0WywyXSA9IGFzLm51bWVyaWModHR0WywyXSkNCg0KKGdncGxvdCh0dHQsIGFlcyhBZ2UscXgsIGZyYW1lPVllYXIsIGdyb3VwPUdlbmRlcikpDQorZ2VvbV9saW5lKGFlcyhjb2xvcj10eXBlKSkNCiAgK2xhYnModGl0bGU9J2NvbXBhcmFpc29uIGRlcyBxeCBvYnNlcnbDqWVzIGV0IGRlcyBxeCBwcsOpZGl0cycsIHk9J1F1b3RpZW50IGRlIG1vcnRhbGl0w6knLCB4PSdhZ2UnKQ0KICArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZT0iYm9sZC5pdGFsaWMiKSkNCiAgKyBmYWNldF9ncmlkKH5HZW5kZXIpK3NjYWxlX3lfbG9nMTAobGFiZWxzPXNjaWVudGlmaWMpDQogICsgdGhlbWVfYncoKSklPiUNCiAgcGxvdGx5OjpnZ3Bsb3RseShoZWlnaHQgPSA1MDAsIHdpZHRoPTgwMCkNCg0KDQpgYGANCg0KDQojIyBQcsOpZGljdGlvbnMgZGUgbCdlc3DDqXJhbmNlIGRlIHZpZSDDoCBkaWZmw6lyZW50cyDDomdlcw0KDQotIFsgXSBVdGlsaXNlciBsJ2FwcHJveGltYXRpb24gZGUgTGVlLUNhcnRlciBwb3VyIGVzdGltZXIgbGVzIGVzcMOpcmFuY2VzIGRlIHZpZSByw6lzaWR1ZWxsZXMuDQotIFsgXSBDb21wYXJlciBhdmVjIGxlcyBlc3DDqXJhbmNlcyBkZSB2aWUgcsOpc2lkdWVsbGVzIG9ic2VydsOpZXMNCg0KIyBSw6lmw6lyZW5jZXMNCg0KX19UYWJsZXMgZGUgbW9ydGFsaXTDqSBldCBkw6ltb2dyYXBoaWVfXw0KDQotIFtIdW1hbiBNb3J0YWxpdHkgRGF0YWJhc2VdKGh0dHBzOi8vd3d3Lm1vcnRhbGl0eS5vcmcpDQotIFtUYWJsZXMgZGUgbW9ydGFsaXTDqSBmcmFuw6dhaXNlcywgSmFjcXVlcyBWYWxsaW4gZXQgRnJhbmNlIE1lc2zDqV0oaHR0cHM6Ly93d3cubGlmZXRhYmxlLmRlL2RhdGEvRlJBL0ZSQTAwMDAxODA2MTk5N0NZMS5wZGYpDQotIFtNb2RlbGluZyBhbmQgRm9yZWNhc3RpbmcgVS5TLiBNb3J0YWxpdHksIFIuRC5MZWUgYW5kIEwuUi4gQ2FydGVyLCBKQVNBIDE5OTJdKGh0dHBzOi8vd3d3LmpzdG9yLm9yZy9zdGFibGUvcGRmLzIyOTAyMDEucGRmKQ0KLSBbTGVzIGRpbWVuc2lvbnMgZGUgbGEgbW9ydGFsaXTDqSwgUy4gTGVkZXJtYW5uLCBKZWFuIEJyZWFzLCBQb3B1bGF0aW9uLCAxOTU5XShodHRwczovL3d3dy5qc3Rvci5vcmcvc3RhYmxlL3BkZi8xNTI2MDgyLnBkZikNCi0gU2FtdWVsIEguIFByZXN0b24sIFBhdHJpY2sgSGV1dmVsaW5lIGFuZCBNaWNoZWwgR3VpbGxvdCwgX0RlbW9ncmFwaHk6IE1lYXN1cmluZyBhbmQgTW9kZWxpbmcgUG9wdWxhdGlvbiBQcm9jZXNzZXNfLCBPeGZvcmQ6IEJsYWNrd2VsbCBQdWJsaXNoZXJzLCAyMDAxLCB4diArIDI5MSBwcC4NCg0KX19HcmFwaGlxdWVzIGV0IHJhcHBvcnRzX18NCg0KLSBbSW50ZXJhY3RpdmUgd2ViLWJhc2VkIGRhdGEgdmlzdWFsaXphdGlvbiB3aXRoIFIsIHBsb3RseSwgYW5kIHNoaW55XShodHRwczovL3Bsb3RseS1yLmNvbS9pbmRleC5odG1sKQ0KLSBbUiBmb3IgRGF0YSBTY2llbmNlXShodHRwczovL3I0ZHMuaGFkLmNvLm56KQ0KLSBbTGF5ZXJlZCBncmFwaGljc10oaHR0cDovL3ZpdGEuaGFkLmNvLm56L3BhcGVycy9sYXllcmVkLWdyYW1tYXIucGRmKQ0KLSBbUGxvdGx5XShodHRwOi8vcGxvdGx5LmNvbS8pDQoNCl9fVGlkeXZlcnNlX18NCg0KLSBbdGlkeXNlbGVjdF0oaHR0cHM6Ly90aWR5c2VsZWN0LnItbGliLm9yZy9hcnRpY2xlcy90aWR5c2VsZWN0Lmh0bWwpDQotIFtkYnBseXJdKGh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL3dlYi9wYWNrYWdlcy9kYnBseXIvdmlnbmV0dGVzL2RicGx5ci5odG1sKQ0KLSBbZGF0YS50YWJsZV0oaHR0cHM6Ly9naXRodWIuY29tL1JkYXRhdGFibGUvZGF0YS50YWJsZSkNCi0gW0RUXShodHRwczovL3JzdHVkaW8uZ2l0aHViLmlvL0RULykNCg0KX19QQ0EsIFNWRF9fDQoNCi0gW0ZhY3RvTWluZVJdKGh0dHA6Ly9mYWN0b21pbmVyLmZyZWUuZnIvaW5kZXhfZnIuaHRtbCkNCi0gW2FkZTRdKGh0dHA6Ly9wYmlsLnVuaXYtbHlvbjEuZnIvYWRlNC9hY2N1ZWlsLnBocCkNCi0gW0ZhY3RvSW52ZXN0aWdhdGVdKGh0dHA6Ly9mYWN0b21pbmVyLmZyZWUuZnIvcmVwb3J0aW5nL2luZGV4X2ZyLmh0bWwpDQotIFtQQ0EgYW5kIFRpZHl2ZXJzZV0oaHR0cHM6Ly9jbWRsaW5ldGlwcy5jb20vMjAxOS8wNS9ob3ctdG8tZG8tcGNhLWluLXRpZHl2ZXJzZS1mcmFtZXdvcmsvKQ0KLSBbdGlkeXByY29tcF0oaHR0cHM6Ly9icm9vbS50aWR5dmVyc2Uub3JnL3JlZmVyZW5jZS90aWR5LnByY29tcC5odG1sKQ0KDQpfX0TDqW1vZ3JhcGhpZV9fDQoNCi0gW1IgcGFja2FnZSBkZW1vZ3JhcGh5XShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvZGVtb2dyYXBoeS9kZW1vZ3JhcGh5LnBkZikNCg0K